xref: /aosp_15_r20/tools/netsim/rust/daemon/src/ffi.rs (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1*cf78ab8cSAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*cf78ab8cSAndroid Build Coastguard Worker //
3*cf78ab8cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cf78ab8cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cf78ab8cSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cf78ab8cSAndroid Build Coastguard Worker //
7*cf78ab8cSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*cf78ab8cSAndroid Build Coastguard Worker //
9*cf78ab8cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cf78ab8cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cf78ab8cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cf78ab8cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cf78ab8cSAndroid Build Coastguard Worker // limitations under the License.
14*cf78ab8cSAndroid Build Coastguard Worker 
15*cf78ab8cSAndroid Build Coastguard Worker //! Netsim daemon cxx libraries.
16*cf78ab8cSAndroid Build Coastguard Worker 
17*cf78ab8cSAndroid Build Coastguard Worker use std::pin::Pin;
18*cf78ab8cSAndroid Build Coastguard Worker 
19*cf78ab8cSAndroid Build Coastguard Worker use crate::bluetooth::chip::{
20*cf78ab8cSAndroid Build Coastguard Worker     create_add_rust_device_result, AddRustDeviceResult, RustBluetoothChipCallbacks,
21*cf78ab8cSAndroid Build Coastguard Worker };
22*cf78ab8cSAndroid Build Coastguard Worker use crate::http_server::server_response::ServerResponseWritable;
23*cf78ab8cSAndroid Build Coastguard Worker use crate::http_server::server_response::StrHeaders;
24*cf78ab8cSAndroid Build Coastguard Worker use cxx::let_cxx_string;
25*cf78ab8cSAndroid Build Coastguard Worker 
26*cf78ab8cSAndroid Build Coastguard Worker use crate::captures::captures_handler::handle_capture_cxx;
27*cf78ab8cSAndroid Build Coastguard Worker use crate::devices::devices_handler::{
28*cf78ab8cSAndroid Build Coastguard Worker     add_chip_cxx, get_distance_cxx, handle_device_cxx, remove_chip_cxx, AddChipResultCxx,
29*cf78ab8cSAndroid Build Coastguard Worker };
30*cf78ab8cSAndroid Build Coastguard Worker use crate::ranging::*;
31*cf78ab8cSAndroid Build Coastguard Worker use crate::version::*;
32*cf78ab8cSAndroid Build Coastguard Worker use crate::wireless::{
33*cf78ab8cSAndroid Build Coastguard Worker     bluetooth::report_invalid_packet_cxx, handle_request_cxx, handle_response_cxx,
34*cf78ab8cSAndroid Build Coastguard Worker };
35*cf78ab8cSAndroid Build Coastguard Worker 
36*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
37*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim::wireless")]
38*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_wireless {
39*cf78ab8cSAndroid Build Coastguard Worker     extern "Rust" {
40*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = HandleRequestCxx]
handle_request_cxx(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8)41*cf78ab8cSAndroid Build Coastguard Worker         fn handle_request_cxx(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8);
42*cf78ab8cSAndroid Build Coastguard Worker 
43*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = HandleResponse]
handle_response_cxx(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8)44*cf78ab8cSAndroid Build Coastguard Worker         fn handle_response_cxx(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8);
45*cf78ab8cSAndroid Build Coastguard Worker     }
46*cf78ab8cSAndroid Build Coastguard Worker }
47*cf78ab8cSAndroid Build Coastguard Worker 
48*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
49*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim::transport")]
50*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_transport {
51*cf78ab8cSAndroid Build Coastguard Worker     unsafe extern "C++" {
52*cf78ab8cSAndroid Build Coastguard Worker         // Grpc client.
53*cf78ab8cSAndroid Build Coastguard Worker         // Expose functions in Cuttlefish only, because it's only used by CVDs and it's
54*cf78ab8cSAndroid Build Coastguard Worker         // unable to pass function pointers on Windows.
55*cf78ab8cSAndroid Build Coastguard Worker         #[cfg(feature = "cuttlefish")]
56*cf78ab8cSAndroid Build Coastguard Worker         include!("backend/grpc_client.h");
57*cf78ab8cSAndroid Build Coastguard Worker 
58*cf78ab8cSAndroid Build Coastguard Worker         #[allow(dead_code)]
59*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = stream_packets]
60*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::backend::client"]
61*cf78ab8cSAndroid Build Coastguard Worker         #[cfg(feature = "cuttlefish")]
StreamPackets(server: &String) -> u3262*cf78ab8cSAndroid Build Coastguard Worker         fn StreamPackets(server: &String) -> u32;
63*cf78ab8cSAndroid Build Coastguard Worker 
64*cf78ab8cSAndroid Build Coastguard Worker         #[allow(dead_code)]
65*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = read_packet_response_loop]
66*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::backend::client"]
67*cf78ab8cSAndroid Build Coastguard Worker         #[cfg(feature = "cuttlefish")]
ReadPacketResponseLoop( stream_id: u32, read_fn: fn(stream_id: u32, proto_bytes: &[u8]), ) -> bool68*cf78ab8cSAndroid Build Coastguard Worker         fn ReadPacketResponseLoop(
69*cf78ab8cSAndroid Build Coastguard Worker             stream_id: u32,
70*cf78ab8cSAndroid Build Coastguard Worker             read_fn: fn(stream_id: u32, proto_bytes: &[u8]),
71*cf78ab8cSAndroid Build Coastguard Worker         ) -> bool;
72*cf78ab8cSAndroid Build Coastguard Worker 
73*cf78ab8cSAndroid Build Coastguard Worker         #[allow(dead_code)]
74*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = write_packet_request]
75*cf78ab8cSAndroid Build Coastguard Worker         #[cfg(feature = "cuttlefish")]
76*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::backend::client"]
WritePacketRequest(stream_id: u32, proto_bytes: &[u8]) -> bool77*cf78ab8cSAndroid Build Coastguard Worker         fn WritePacketRequest(stream_id: u32, proto_bytes: &[u8]) -> bool;
78*cf78ab8cSAndroid Build Coastguard Worker 
79*cf78ab8cSAndroid Build Coastguard Worker     }
80*cf78ab8cSAndroid Build Coastguard Worker }
81*cf78ab8cSAndroid Build Coastguard Worker 
82*cf78ab8cSAndroid Build Coastguard Worker #[allow(clippy::needless_maybe_sized)]
83*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
84*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim")]
85*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_bluetooth {
86*cf78ab8cSAndroid Build Coastguard Worker     extern "Rust" {
87*cf78ab8cSAndroid Build Coastguard Worker         // Rust Bluetooth device.
88*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
89*cf78ab8cSAndroid Build Coastguard Worker         type DynRustBluetoothChipCallbacks;
90*cf78ab8cSAndroid Build Coastguard Worker 
91*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = Tick]
92*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
tick(dyn_callbacks: &mut DynRustBluetoothChipCallbacks)93*cf78ab8cSAndroid Build Coastguard Worker         fn tick(dyn_callbacks: &mut DynRustBluetoothChipCallbacks);
94*cf78ab8cSAndroid Build Coastguard Worker 
95*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = ReceiveLinkLayerPacket]
96*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
receive_link_layer_packet( dyn_callbacks: &mut DynRustBluetoothChipCallbacks, source_address: String, destination_address: String, packet_type: u8, packet: &[u8], )97*cf78ab8cSAndroid Build Coastguard Worker         fn receive_link_layer_packet(
98*cf78ab8cSAndroid Build Coastguard Worker             dyn_callbacks: &mut DynRustBluetoothChipCallbacks,
99*cf78ab8cSAndroid Build Coastguard Worker             source_address: String,
100*cf78ab8cSAndroid Build Coastguard Worker             destination_address: String,
101*cf78ab8cSAndroid Build Coastguard Worker             packet_type: u8,
102*cf78ab8cSAndroid Build Coastguard Worker             packet: &[u8],
103*cf78ab8cSAndroid Build Coastguard Worker         );
104*cf78ab8cSAndroid Build Coastguard Worker 
105*cf78ab8cSAndroid Build Coastguard Worker         // Bluetooth facade.
106*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
107*cf78ab8cSAndroid Build Coastguard Worker         type AddRustDeviceResult;
108*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "CreateAddRustDeviceResult"]
109*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci"]
create_add_rust_device_result( facade_id: u32, rust_chip: UniquePtr<RustBluetoothChip>, ) -> Box<AddRustDeviceResult>110*cf78ab8cSAndroid Build Coastguard Worker         fn create_add_rust_device_result(
111*cf78ab8cSAndroid Build Coastguard Worker             facade_id: u32,
112*cf78ab8cSAndroid Build Coastguard Worker             rust_chip: UniquePtr<RustBluetoothChip>,
113*cf78ab8cSAndroid Build Coastguard Worker         ) -> Box<AddRustDeviceResult>;
114*cf78ab8cSAndroid Build Coastguard Worker 
115*cf78ab8cSAndroid Build Coastguard Worker         // Rust Invalid Packet Report
116*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "ReportInvalidPacket"]
117*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
report_invalid_packet_cxx( rootcanal_id: u32, reason: i32, description: &CxxString, packet: &CxxVector<u8>, )118*cf78ab8cSAndroid Build Coastguard Worker         fn report_invalid_packet_cxx(
119*cf78ab8cSAndroid Build Coastguard Worker             rootcanal_id: u32,
120*cf78ab8cSAndroid Build Coastguard Worker             reason: i32,
121*cf78ab8cSAndroid Build Coastguard Worker             description: &CxxString,
122*cf78ab8cSAndroid Build Coastguard Worker             packet: &CxxVector<u8>,
123*cf78ab8cSAndroid Build Coastguard Worker         );
124*cf78ab8cSAndroid Build Coastguard Worker     }
125*cf78ab8cSAndroid Build Coastguard Worker 
126*cf78ab8cSAndroid Build Coastguard Worker     #[allow(dead_code)]
127*cf78ab8cSAndroid Build Coastguard Worker     unsafe extern "C++" {
128*cf78ab8cSAndroid Build Coastguard Worker         // Bluetooth facade.
129*cf78ab8cSAndroid Build Coastguard Worker         include!("hci/hci_packet_hub.h");
130*cf78ab8cSAndroid Build Coastguard Worker 
131*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = handle_bt_request]
132*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci"]
HandleBtRequestCxx(rootcanal_id: u32, packet_type: u8, packet: &Vec<u8>)133*cf78ab8cSAndroid Build Coastguard Worker         fn HandleBtRequestCxx(rootcanal_id: u32, packet_type: u8, packet: &Vec<u8>);
134*cf78ab8cSAndroid Build Coastguard Worker 
135*cf78ab8cSAndroid Build Coastguard Worker         // Rust Bluetooth device.
136*cf78ab8cSAndroid Build Coastguard Worker         include!("hci/rust_device.h");
137*cf78ab8cSAndroid Build Coastguard Worker 
138*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
139*cf78ab8cSAndroid Build Coastguard Worker         type RustBluetoothChip;
140*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = send_link_layer_le_packet]
141*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
SendLinkLayerLePacket(self: &RustBluetoothChip, packet: &[u8], tx_power: i8)142*cf78ab8cSAndroid Build Coastguard Worker         fn SendLinkLayerLePacket(self: &RustBluetoothChip, packet: &[u8], tx_power: i8);
143*cf78ab8cSAndroid Build Coastguard Worker 
144*cf78ab8cSAndroid Build Coastguard Worker         include!("hci/bluetooth_facade.h");
145*cf78ab8cSAndroid Build Coastguard Worker 
146*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_get_cxx]
147*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
GetCxx(rootcanal_id: u32) -> Vec<u8>148*cf78ab8cSAndroid Build Coastguard Worker         pub fn GetCxx(rootcanal_id: u32) -> Vec<u8>;
149*cf78ab8cSAndroid Build Coastguard Worker 
150*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_reset]
151*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
Reset(rootcanal_id: u32)152*cf78ab8cSAndroid Build Coastguard Worker         pub fn Reset(rootcanal_id: u32);
153*cf78ab8cSAndroid Build Coastguard Worker 
154*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_remove]
155*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
Remove(rootcanal_id: u32)156*cf78ab8cSAndroid Build Coastguard Worker         pub fn Remove(rootcanal_id: u32);
157*cf78ab8cSAndroid Build Coastguard Worker 
158*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_add]
159*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
Add(chip_id: u32, address: &CxxString, controller_proto_bytes: &[u8]) -> u32160*cf78ab8cSAndroid Build Coastguard Worker         pub fn Add(chip_id: u32, address: &CxxString, controller_proto_bytes: &[u8]) -> u32;
161*cf78ab8cSAndroid Build Coastguard Worker 
162*cf78ab8cSAndroid Build Coastguard Worker         /*
163*cf78ab8cSAndroid Build Coastguard Worker         From https://cxx.rs/binding/box.html#restrictions,
164*cf78ab8cSAndroid Build Coastguard Worker         ```
165*cf78ab8cSAndroid Build Coastguard Worker         If T is an opaque Rust type, the Rust type is required to be Sized i.e. size known at compile time. In the future we may introduce support for dynamically sized opaque Rust types.
166*cf78ab8cSAndroid Build Coastguard Worker         ```
167*cf78ab8cSAndroid Build Coastguard Worker 
168*cf78ab8cSAndroid Build Coastguard Worker         The workaround is using Box<dyn MyData> (fat pointer) as the opaque type.
169*cf78ab8cSAndroid Build Coastguard Worker         Reference:
170*cf78ab8cSAndroid Build Coastguard Worker         - Passing trait objects to C++. https://github.com/dtolnay/cxx/issues/665.
171*cf78ab8cSAndroid Build Coastguard Worker         - Exposing trait methods to C++. https://github.com/dtolnay/cxx/issues/667
172*cf78ab8cSAndroid Build Coastguard Worker                 */
173*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_add_rust_device]
174*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
AddRustDevice( chip_id: u32, callbacks: Box<DynRustBluetoothChipCallbacks>, string_type: &CxxString, address: &CxxString, ) -> Box<AddRustDeviceResult>175*cf78ab8cSAndroid Build Coastguard Worker         pub fn AddRustDevice(
176*cf78ab8cSAndroid Build Coastguard Worker             chip_id: u32,
177*cf78ab8cSAndroid Build Coastguard Worker             callbacks: Box<DynRustBluetoothChipCallbacks>,
178*cf78ab8cSAndroid Build Coastguard Worker             string_type: &CxxString,
179*cf78ab8cSAndroid Build Coastguard Worker             address: &CxxString,
180*cf78ab8cSAndroid Build Coastguard Worker         ) -> Box<AddRustDeviceResult>;
181*cf78ab8cSAndroid Build Coastguard Worker 
182*cf78ab8cSAndroid Build Coastguard Worker         /// The provided address must be 6 bytes in length
183*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_set_rust_device_address]
184*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
SetRustDeviceAddress(rootcanal_id: u32, address: [u8; 6])185*cf78ab8cSAndroid Build Coastguard Worker         pub fn SetRustDeviceAddress(rootcanal_id: u32, address: [u8; 6]);
186*cf78ab8cSAndroid Build Coastguard Worker 
187*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_remove_rust_device]
188*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
RemoveRustDevice(rootcanal_id: u32)189*cf78ab8cSAndroid Build Coastguard Worker         pub fn RemoveRustDevice(rootcanal_id: u32);
190*cf78ab8cSAndroid Build Coastguard Worker 
191*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_start]
192*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
Start(proto_bytes: &[u8], instance_num: u16)193*cf78ab8cSAndroid Build Coastguard Worker         pub fn Start(proto_bytes: &[u8], instance_num: u16);
194*cf78ab8cSAndroid Build Coastguard Worker 
195*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = bluetooth_stop]
196*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
Stop()197*cf78ab8cSAndroid Build Coastguard Worker         pub fn Stop();
198*cf78ab8cSAndroid Build Coastguard Worker 
199*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = add_device_to_phy]
200*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
AddDeviceToPhy(rootcanal_id: u32, is_low_energy: bool)201*cf78ab8cSAndroid Build Coastguard Worker         pub fn AddDeviceToPhy(rootcanal_id: u32, is_low_energy: bool);
202*cf78ab8cSAndroid Build Coastguard Worker 
203*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = remove_device_from_phy]
204*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::hci::facade"]
RemoveDeviceFromPhy(rootcanal_id: u32, is_low_energy: bool)205*cf78ab8cSAndroid Build Coastguard Worker         pub fn RemoveDeviceFromPhy(rootcanal_id: u32, is_low_energy: bool);
206*cf78ab8cSAndroid Build Coastguard Worker     }
207*cf78ab8cSAndroid Build Coastguard Worker }
208*cf78ab8cSAndroid Build Coastguard Worker 
209*cf78ab8cSAndroid Build Coastguard Worker #[allow(clippy::needless_maybe_sized)]
210*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
211*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim::device")]
212*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_devices {
213*cf78ab8cSAndroid Build Coastguard Worker     extern "Rust" {
214*cf78ab8cSAndroid Build Coastguard Worker 
215*cf78ab8cSAndroid Build Coastguard Worker         // Device Resource
216*cf78ab8cSAndroid Build Coastguard Worker         type AddChipResultCxx;
217*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "GetDeviceId"]
get_device_id(self: &AddChipResultCxx) -> u32218*cf78ab8cSAndroid Build Coastguard Worker         fn get_device_id(self: &AddChipResultCxx) -> u32;
219*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "GetChipId"]
get_chip_id(self: &AddChipResultCxx) -> u32220*cf78ab8cSAndroid Build Coastguard Worker         fn get_chip_id(self: &AddChipResultCxx) -> u32;
221*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "IsError"]
is_error(self: &AddChipResultCxx) -> bool222*cf78ab8cSAndroid Build Coastguard Worker         fn is_error(self: &AddChipResultCxx) -> bool;
223*cf78ab8cSAndroid Build Coastguard Worker 
224*cf78ab8cSAndroid Build Coastguard Worker         #[allow(clippy::too_many_arguments)]
225*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = AddChipCxx]
add_chip_cxx( device_guid: &str, device_name: &str, chip_kind: &CxxString, chip_address: &str, chip_name: &str, chip_manufacturer: &str, chip_product_name: &str, bt_properties: &CxxVector<u8>, kind: &str, version: &str, sdk_version: &str, build_id: &str, variant: &str, arch: &str, ) -> Box<AddChipResultCxx>226*cf78ab8cSAndroid Build Coastguard Worker         fn add_chip_cxx(
227*cf78ab8cSAndroid Build Coastguard Worker             device_guid: &str,
228*cf78ab8cSAndroid Build Coastguard Worker             device_name: &str,
229*cf78ab8cSAndroid Build Coastguard Worker             chip_kind: &CxxString,
230*cf78ab8cSAndroid Build Coastguard Worker             chip_address: &str,
231*cf78ab8cSAndroid Build Coastguard Worker             chip_name: &str,
232*cf78ab8cSAndroid Build Coastguard Worker             chip_manufacturer: &str,
233*cf78ab8cSAndroid Build Coastguard Worker             chip_product_name: &str,
234*cf78ab8cSAndroid Build Coastguard Worker             bt_properties: &CxxVector<u8>,
235*cf78ab8cSAndroid Build Coastguard Worker             kind: &str,
236*cf78ab8cSAndroid Build Coastguard Worker             version: &str,
237*cf78ab8cSAndroid Build Coastguard Worker             sdk_version: &str,
238*cf78ab8cSAndroid Build Coastguard Worker             build_id: &str,
239*cf78ab8cSAndroid Build Coastguard Worker             variant: &str,
240*cf78ab8cSAndroid Build Coastguard Worker             arch: &str,
241*cf78ab8cSAndroid Build Coastguard Worker         ) -> Box<AddChipResultCxx>;
242*cf78ab8cSAndroid Build Coastguard Worker 
243*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = RemoveChipCxx]
remove_chip_cxx(device_id: u32, chip_id: u32)244*cf78ab8cSAndroid Build Coastguard Worker         fn remove_chip_cxx(device_id: u32, chip_id: u32);
245*cf78ab8cSAndroid Build Coastguard Worker 
246*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = GetDistanceCxx]
get_distance_cxx(a: u32, b: u32) -> f32247*cf78ab8cSAndroid Build Coastguard Worker         fn get_distance_cxx(a: u32, b: u32) -> f32;
248*cf78ab8cSAndroid Build Coastguard Worker     }
249*cf78ab8cSAndroid Build Coastguard Worker }
250*cf78ab8cSAndroid Build Coastguard Worker 
251*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
252*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim")]
253*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_response_writable {
254*cf78ab8cSAndroid Build Coastguard Worker     extern "Rust" {
255*cf78ab8cSAndroid Build Coastguard Worker         // handlers for gRPC server's invocation of API calls
256*cf78ab8cSAndroid Build Coastguard Worker 
257*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "HandleCaptureCxx"]
handle_capture_cxx( responder: Pin<&mut CxxServerResponseWriter>, method: String, param: String, body: String, )258*cf78ab8cSAndroid Build Coastguard Worker         fn handle_capture_cxx(
259*cf78ab8cSAndroid Build Coastguard Worker             responder: Pin<&mut CxxServerResponseWriter>,
260*cf78ab8cSAndroid Build Coastguard Worker             method: String,
261*cf78ab8cSAndroid Build Coastguard Worker             param: String,
262*cf78ab8cSAndroid Build Coastguard Worker             body: String,
263*cf78ab8cSAndroid Build Coastguard Worker         );
264*cf78ab8cSAndroid Build Coastguard Worker 
265*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "HandleDeviceCxx"]
handle_device_cxx( responder: Pin<&mut CxxServerResponseWriter>, method: String, param: String, body: String, )266*cf78ab8cSAndroid Build Coastguard Worker         fn handle_device_cxx(
267*cf78ab8cSAndroid Build Coastguard Worker             responder: Pin<&mut CxxServerResponseWriter>,
268*cf78ab8cSAndroid Build Coastguard Worker             method: String,
269*cf78ab8cSAndroid Build Coastguard Worker             param: String,
270*cf78ab8cSAndroid Build Coastguard Worker             body: String,
271*cf78ab8cSAndroid Build Coastguard Worker         );
272*cf78ab8cSAndroid Build Coastguard Worker     }
273*cf78ab8cSAndroid Build Coastguard Worker     unsafe extern "C++" {
274*cf78ab8cSAndroid Build Coastguard Worker         /// A C++ class which can be used to respond to a request.
275*cf78ab8cSAndroid Build Coastguard Worker         include!("frontend/server_response_writable.h");
276*cf78ab8cSAndroid Build Coastguard Worker 
277*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::frontend"]
278*cf78ab8cSAndroid Build Coastguard Worker         type CxxServerResponseWriter;
279*cf78ab8cSAndroid Build Coastguard Worker 
280*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::frontend"]
put_ok_with_length(self: &CxxServerResponseWriter, mime_type: &CxxString, length: usize)281*cf78ab8cSAndroid Build Coastguard Worker         fn put_ok_with_length(self: &CxxServerResponseWriter, mime_type: &CxxString, length: usize);
282*cf78ab8cSAndroid Build Coastguard Worker 
283*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::frontend"]
put_chunk(self: &CxxServerResponseWriter, chunk: &[u8])284*cf78ab8cSAndroid Build Coastguard Worker         fn put_chunk(self: &CxxServerResponseWriter, chunk: &[u8]);
285*cf78ab8cSAndroid Build Coastguard Worker 
286*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::frontend"]
put_ok(self: &CxxServerResponseWriter, mime_type: &CxxString, body: &CxxString)287*cf78ab8cSAndroid Build Coastguard Worker         fn put_ok(self: &CxxServerResponseWriter, mime_type: &CxxString, body: &CxxString);
288*cf78ab8cSAndroid Build Coastguard Worker 
289*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim::frontend"]
put_error(self: &CxxServerResponseWriter, error_code: u32, error_message: &CxxString)290*cf78ab8cSAndroid Build Coastguard Worker         fn put_error(self: &CxxServerResponseWriter, error_code: u32, error_message: &CxxString);
291*cf78ab8cSAndroid Build Coastguard Worker 
292*cf78ab8cSAndroid Build Coastguard Worker     }
293*cf78ab8cSAndroid Build Coastguard Worker }
294*cf78ab8cSAndroid Build Coastguard Worker 
295*cf78ab8cSAndroid Build Coastguard Worker #[allow(unsafe_op_in_unsafe_fn)]
296*cf78ab8cSAndroid Build Coastguard Worker #[cxx::bridge(namespace = "netsim")]
297*cf78ab8cSAndroid Build Coastguard Worker pub mod ffi_util {
298*cf78ab8cSAndroid Build Coastguard Worker     extern "Rust" {
299*cf78ab8cSAndroid Build Coastguard Worker         // Ranging
300*cf78ab8cSAndroid Build Coastguard Worker 
301*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "DistanceToRssi"]
distance_to_rssi(tx_power: i8, distance: f32) -> i8302*cf78ab8cSAndroid Build Coastguard Worker         fn distance_to_rssi(tx_power: i8, distance: f32) -> i8;
303*cf78ab8cSAndroid Build Coastguard Worker 
304*cf78ab8cSAndroid Build Coastguard Worker         // Version
305*cf78ab8cSAndroid Build Coastguard Worker 
306*cf78ab8cSAndroid Build Coastguard Worker         #[cxx_name = "GetVersion"]
get_version() -> String307*cf78ab8cSAndroid Build Coastguard Worker         fn get_version() -> String;
308*cf78ab8cSAndroid Build Coastguard Worker     }
309*cf78ab8cSAndroid Build Coastguard Worker 
310*cf78ab8cSAndroid Build Coastguard Worker     #[allow(dead_code)]
311*cf78ab8cSAndroid Build Coastguard Worker     unsafe extern "C++" {
312*cf78ab8cSAndroid Build Coastguard Worker 
313*cf78ab8cSAndroid Build Coastguard Worker         // Crash report.
314*cf78ab8cSAndroid Build Coastguard Worker         include!("util/crash_report.h");
315*cf78ab8cSAndroid Build Coastguard Worker 
316*cf78ab8cSAndroid Build Coastguard Worker         #[rust_name = set_up_crash_report]
317*cf78ab8cSAndroid Build Coastguard Worker         #[namespace = "netsim"]
SetUpCrashReport()318*cf78ab8cSAndroid Build Coastguard Worker         pub fn SetUpCrashReport();
319*cf78ab8cSAndroid Build Coastguard Worker     }
320*cf78ab8cSAndroid Build Coastguard Worker }
321*cf78ab8cSAndroid Build Coastguard Worker 
322*cf78ab8cSAndroid Build Coastguard Worker // It's required so `RustBluetoothChip` can be sent between threads safely.
323*cf78ab8cSAndroid Build Coastguard Worker // Ref: How to use opaque types in threads? https://github.com/dtolnay/cxx/issues/1175
324*cf78ab8cSAndroid Build Coastguard Worker // SAFETY: Nothing in `RustBluetoothChip` depends on being run on a particular thread.
325*cf78ab8cSAndroid Build Coastguard Worker unsafe impl Send for ffi_bluetooth::RustBluetoothChip {}
326*cf78ab8cSAndroid Build Coastguard Worker 
327*cf78ab8cSAndroid Build Coastguard Worker type DynRustBluetoothChipCallbacks = Box<dyn RustBluetoothChipCallbacks>;
328*cf78ab8cSAndroid Build Coastguard Worker 
tick(dyn_callbacks: &mut DynRustBluetoothChipCallbacks)329*cf78ab8cSAndroid Build Coastguard Worker fn tick(dyn_callbacks: &mut DynRustBluetoothChipCallbacks) {
330*cf78ab8cSAndroid Build Coastguard Worker     (**dyn_callbacks).tick();
331*cf78ab8cSAndroid Build Coastguard Worker }
332*cf78ab8cSAndroid Build Coastguard Worker 
receive_link_layer_packet( dyn_callbacks: &mut DynRustBluetoothChipCallbacks, source_address: String, destination_address: String, packet_type: u8, packet: &[u8], )333*cf78ab8cSAndroid Build Coastguard Worker fn receive_link_layer_packet(
334*cf78ab8cSAndroid Build Coastguard Worker     dyn_callbacks: &mut DynRustBluetoothChipCallbacks,
335*cf78ab8cSAndroid Build Coastguard Worker     source_address: String,
336*cf78ab8cSAndroid Build Coastguard Worker     destination_address: String,
337*cf78ab8cSAndroid Build Coastguard Worker     packet_type: u8,
338*cf78ab8cSAndroid Build Coastguard Worker     packet: &[u8],
339*cf78ab8cSAndroid Build Coastguard Worker ) {
340*cf78ab8cSAndroid Build Coastguard Worker     (**dyn_callbacks).receive_link_layer_packet(
341*cf78ab8cSAndroid Build Coastguard Worker         source_address,
342*cf78ab8cSAndroid Build Coastguard Worker         destination_address,
343*cf78ab8cSAndroid Build Coastguard Worker         packet_type,
344*cf78ab8cSAndroid Build Coastguard Worker         packet,
345*cf78ab8cSAndroid Build Coastguard Worker     );
346*cf78ab8cSAndroid Build Coastguard Worker }
347*cf78ab8cSAndroid Build Coastguard Worker 
348*cf78ab8cSAndroid Build Coastguard Worker /// CxxServerResponseWriter is defined in server_response_writable.h
349*cf78ab8cSAndroid Build Coastguard Worker /// Wrapper struct allows the impl to discover the respective C++ methods
350*cf78ab8cSAndroid Build Coastguard Worker pub struct CxxServerResponseWriterWrapper<'a> {
351*cf78ab8cSAndroid Build Coastguard Worker     pub writer: Pin<&'a mut ffi_response_writable::CxxServerResponseWriter>,
352*cf78ab8cSAndroid Build Coastguard Worker }
353*cf78ab8cSAndroid Build Coastguard Worker 
354*cf78ab8cSAndroid Build Coastguard Worker impl ServerResponseWritable for CxxServerResponseWriterWrapper<'_> {
put_ok_with_length(&mut self, mime_type: &str, length: usize, _headers: StrHeaders)355*cf78ab8cSAndroid Build Coastguard Worker     fn put_ok_with_length(&mut self, mime_type: &str, length: usize, _headers: StrHeaders) {
356*cf78ab8cSAndroid Build Coastguard Worker         let_cxx_string!(mime_type = mime_type);
357*cf78ab8cSAndroid Build Coastguard Worker         self.writer.put_ok_with_length(&mime_type, length);
358*cf78ab8cSAndroid Build Coastguard Worker     }
put_chunk(&mut self, chunk: &[u8])359*cf78ab8cSAndroid Build Coastguard Worker     fn put_chunk(&mut self, chunk: &[u8]) {
360*cf78ab8cSAndroid Build Coastguard Worker         self.writer.put_chunk(chunk);
361*cf78ab8cSAndroid Build Coastguard Worker     }
put_ok(&mut self, mime_type: &str, body: &str, _headers: StrHeaders)362*cf78ab8cSAndroid Build Coastguard Worker     fn put_ok(&mut self, mime_type: &str, body: &str, _headers: StrHeaders) {
363*cf78ab8cSAndroid Build Coastguard Worker         let_cxx_string!(mime_type = mime_type);
364*cf78ab8cSAndroid Build Coastguard Worker         let_cxx_string!(body = body);
365*cf78ab8cSAndroid Build Coastguard Worker         self.writer.put_ok(&mime_type, &body);
366*cf78ab8cSAndroid Build Coastguard Worker     }
put_error(&mut self, error_code: u16, error_message: &str)367*cf78ab8cSAndroid Build Coastguard Worker     fn put_error(&mut self, error_code: u16, error_message: &str) {
368*cf78ab8cSAndroid Build Coastguard Worker         let_cxx_string!(error_message = error_message);
369*cf78ab8cSAndroid Build Coastguard Worker         self.writer.put_error(error_code.into(), &error_message);
370*cf78ab8cSAndroid Build Coastguard Worker     }
371*cf78ab8cSAndroid Build Coastguard Worker 
put_ok_with_vec(&mut self, _mime_type: &str, _body: Vec<u8>, _headers: StrHeaders)372*cf78ab8cSAndroid Build Coastguard Worker     fn put_ok_with_vec(&mut self, _mime_type: &str, _body: Vec<u8>, _headers: StrHeaders) {
373*cf78ab8cSAndroid Build Coastguard Worker         todo!()
374*cf78ab8cSAndroid Build Coastguard Worker     }
put_ok_switch_protocol(&mut self, _connection: &str, _headers: StrHeaders)375*cf78ab8cSAndroid Build Coastguard Worker     fn put_ok_switch_protocol(&mut self, _connection: &str, _headers: StrHeaders) {
376*cf78ab8cSAndroid Build Coastguard Worker         todo!()
377*cf78ab8cSAndroid Build Coastguard Worker     }
378*cf78ab8cSAndroid Build Coastguard Worker }
379