diff --git a/system/bta/BUILD.gn b/system/bta/BUILD.gn index ab7c327f5861e30294c1ad086447e4e18934ad2b..b8b32eaac57c980f457783274d5f3fc473585b11 100644 --- a/system/bta/BUILD.gn +++ b/system/bta/BUILD.gn @@ -117,7 +117,7 @@ static_library("bta") { ] deps = [ - "//bt/gd/rust/shim:hci_bridge_header", + "//bt/gd/rust/shim:shim_bridge_header", "//bt/gd/rust/shim:init_flags_bridge_header", "//bt/gd/rust/shim:message_loop_thread_bridge_header", ] diff --git a/system/build/Android.bp b/system/build/Android.bp index 75a4d4f04d35c6cfe313ea3c96059c89997eec4a..2bd18c79a3fbc8346955742639ddb947beca30e0 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -81,7 +81,7 @@ fluoride_defaults { defaults: ["fluoride_types_defaults_fuzzable"], header_libs: ["libbluetooth_headers", "libbt_callbacks_cxx_headers"], generated_headers: [ - "libbt_hci_bridge_header", + "libbt_shim_bridge_header", "libbt_message_loop_thread_bridge_header", "cxx-bridge-header" ], diff --git a/system/gd/rust/common/src/sys_prop.rs b/system/gd/rust/common/src/sys_prop.rs index db0779f4c17b216646b2f863c42dd96a82526cba..301311c9f02e6f8dd21c107a17093711bbda330e 100644 --- a/system/gd/rust/common/src/sys_prop.rs +++ b/system/gd/rust/common/src/sys_prop.rs @@ -1,14 +1,19 @@ //! System properties on Android #[cfg(target_os = "android")] -#[cxx::bridge(namespace = bluetooth::common::sys_prop)] -mod ffi { - extern "C" { - include!("src/ffi/sys_prop.h"); - fn get(name: &str) -> String; +mod wrap { + #[cxx::bridge(namespace = bluetooth::common::sys_prop)] + pub mod ffi { + unsafe extern "C++" { + include!("src/ffi/sys_prop.h"); + fn get(name: &str) -> String; + } } } +#[cfg(target_os = "android")] +use wrap::ffi; + /// Gets the value of a system property on Android #[cfg(target_os = "android")] pub fn get(name: &str) -> Option<String> { @@ -43,7 +48,7 @@ pub fn get_bool(name: &str) -> Option<bool> { match value.as_str() { "0" | "n" | "no" | "false" | "off" => Some(false), "1" | "y" | "yes" | "true" | "on" => Some(true), - _ => None + _ => None, } } else { None diff --git a/system/gd/rust/hal/src/ffi/hidl.cc b/system/gd/rust/hal/src/ffi/hidl.cc index 93bf94d2f1be6b779d385a0401c48b39e269da00..fd46babd757d4461fb4762c83d94a1fdfda15f1d 100644 --- a/system/gd/rust/hal/src/ffi/hidl.cc +++ b/system/gd/rust/hal/src/ffi/hidl.cc @@ -99,22 +99,22 @@ void stop_hal() { trampoline_ = nullptr; } -void send_command(rust::Slice<uint8_t> data) { +void send_command(rust::Slice<const uint8_t> data) { ASSERT(bt_hci_ != nullptr); bt_hci_->sendHciCommand(hidl_vec<uint8_t>(data.data(), data.data() + data.length())); } -void send_acl(rust::Slice<uint8_t> data) { +void send_acl(rust::Slice<const uint8_t> data) { ASSERT(bt_hci_ != nullptr); bt_hci_->sendAclData(hidl_vec<uint8_t>(data.data(), data.data() + data.length())); } -void send_sco(rust::Slice<uint8_t> data) { +void send_sco(rust::Slice<const uint8_t> data) { ASSERT(bt_hci_ != nullptr); bt_hci_->sendScoData(hidl_vec<uint8_t>(data.data(), data.data() + data.length())); } -void send_iso(rust::Slice<uint8_t> data) { +void send_iso(rust::Slice<const uint8_t> data) { if (bt_hci_1_1_ == nullptr) { LOG_ERROR("ISO is not supported in HAL v1.0"); return; diff --git a/system/gd/rust/hal/src/ffi/hidl.h b/system/gd/rust/hal/src/ffi/hidl.h index df8a6860980573d9607ab46b5aed171bec1adeb8..20138f64c590c86c3324a24dc01f9286a27d2de6 100644 --- a/system/gd/rust/hal/src/ffi/hidl.h +++ b/system/gd/rust/hal/src/ffi/hidl.h @@ -6,10 +6,10 @@ namespace hal { void start_hal(); void stop_hal(); -void send_command(rust::Slice<uint8_t> data); -void send_acl(rust::Slice<uint8_t> data); -void send_sco(rust::Slice<uint8_t> data); -void send_iso(rust::Slice<uint8_t> data); +void send_command(rust::Slice<const uint8_t> data); +void send_acl(rust::Slice<const uint8_t> data); +void send_sco(rust::Slice<const uint8_t> data); +void send_iso(rust::Slice<const uint8_t> data); } // namespace hal } // namespace bluetooth diff --git a/system/gd/rust/hal/src/hidl_hal.rs b/system/gd/rust/hal/src/hidl_hal.rs index 35b2fded8f308f97cd2a03ba990bcfd079f8500c..ea815e697b7b161780e8daa335d5eadeca6a7904 100644 --- a/system/gd/rust/hal/src/hidl_hal.rs +++ b/system/gd/rust/hal/src/hidl_hal.rs @@ -34,8 +34,10 @@ async fn provide_hidl_hal(rt: Arc<Runtime>) -> RawHal { } #[cxx::bridge(namespace = bluetooth::hal)] +// TODO Either use or remove these functions, this shouldn't be the long term state +#[allow(dead_code)] mod ffi { - extern "C" { + unsafe extern "C++" { include!("src/ffi/hidl.h"); fn start_hal(); fn stop_hal(); diff --git a/system/gd/rust/shim/Android.bp b/system/gd/rust/shim/Android.bp index 9887a6185e153f29501fd31303984f17e80bd21c..5506e1100f7d89ac0fc6a175fd5c3bbab4e10439 100644 --- a/system/gd/rust/shim/Android.bp +++ b/system/gd/rust/shim/Android.bp @@ -59,23 +59,17 @@ cc_library_static { generated_headers: [ "libbt_init_flags_bridge_header", "libbt_shim_bridge_header", - "libbt_hci_bridge_header", - "libbt_controller_bridge_header", "libbt_message_loop_thread_bridge_header", "cxx-bridge-header", ], generated_sources: [ "libbt_init_flags_bridge_code", "libbt_shim_bridge_code", - "libbt_hci_bridge_code", - "libbt_controller_bridge_code", "libbt_message_loop_thread_bridge_code", ], export_generated_headers: [ "libbt_init_flags_bridge_header", "libbt_shim_bridge_header", - "libbt_hci_bridge_header", - "libbt_controller_bridge_header", "libbt_message_loop_thread_bridge_header", "cxx-bridge-header", ], @@ -102,7 +96,7 @@ cc_library_static { defaults: ["gd_ffi_defaults"], header_libs: ["libbt_callbacks_cxx_headers"], srcs: ["callbacks/callbacks.cc"], - generated_headers: ["libbt_hci_bridge_header", "cxx-bridge-header"], + generated_headers: ["libbt_shim_bridge_header", "cxx-bridge-header"], shared_libs: [ "libchrome", ], @@ -119,16 +113,16 @@ genrule { name: "libbt_shim_bridge_header", tools: ["cxxbridge"], cmd: "$(location cxxbridge) $(in) --header > $(out)", - srcs: ["src/stack.rs"], - out: ["src/stack.rs.h"], + srcs: ["src/bridge.rs"], + out: ["src/bridge.rs.h"], } genrule { name: "libbt_shim_bridge_code", tools: ["cxxbridge"], cmd: "$(location cxxbridge) $(in) >> $(out)", - srcs: ["src/stack.rs"], - out: ["stack.cc"], + srcs: ["src/bridge.rs"], + out: ["bridge.cc"], } genrule { @@ -147,22 +141,6 @@ genrule { out: ["init_flags.cc"], } -genrule { - name: "libbt_hci_bridge_header", - tools: ["cxxbridge"], - cmd: "$(location cxxbridge) $(in) --header > $(out)", - srcs: ["src/hci.rs"], - out: ["src/hci.rs.h"], -} - -genrule { - name: "libbt_hci_bridge_code", - tools: ["cxxbridge"], - cmd: "$(location cxxbridge) $(in) >> $(out)", - srcs: ["src/hci.rs"], - out: ["hci.cc"], -} - genrule { name: "libbt_message_loop_thread_bridge_header", tools: ["cxxbridge"], @@ -178,19 +156,3 @@ genrule { srcs: ["src/message_loop_thread.rs"], out: ["message_loop_thread.cc"], } - -genrule { - name: "libbt_controller_bridge_header", - tools: ["cxxbridge"], - cmd: "$(location cxxbridge) $(in) --header > $(out)", - srcs: ["src/controller.rs"], - out: ["src/controller.rs.h"], -} - -genrule { - name: "libbt_controller_bridge_code", - tools: ["cxxbridge"], - cmd: "$(location cxxbridge) $(in) >> $(out)", - srcs: ["src/controller.rs"], - out: ["controller.cc"], -} diff --git a/system/gd/rust/shim/BUILD.gn b/system/gd/rust/shim/BUILD.gn index c0912e90e4b819440d0fb5f6eeeb6bb7fb16e16d..9402ac25905897060b7e0b61b583366d534ee58a 100644 --- a/system/gd/rust/shim/BUILD.gn +++ b/system/gd/rust/shim/BUILD.gn @@ -18,23 +18,16 @@ import("//common-mk/cxxbridge.gni") config("rust_shim_config") { include_dirs = [ "//bt/gd/rust/shim" ] - - ldflags = [ - # Opaque types in rust shim cause duplicate definitions of layout. Use the - # first defined symbol instead of aborting. - # i.e. T::layout::size() and T::layout::align() - "-Wl,--allow-multiple-definition", - ] } cxxbridge_header("shim_bridge_header") { - sources = [ "src/stack.rs" ] + sources = [ "src/bridge.rs" ] all_dependent_configs = [ ":rust_shim_config" ] deps = [ ":cxxlibheader" ] } cxxbridge_cc("shim_bridge_code") { - sources = [ "src/stack.rs" ] + sources = [ "src/bridge.rs" ] deps = [ ":shim_bridge_header" ] configs = [ "//bt/gd:gd_defaults" ] } @@ -51,18 +44,6 @@ cxxbridge_cc("init_flags_bridge_code") { configs = [ "//bt/gd:gd_defaults" ] } -cxxbridge_header("hci_bridge_header") { - sources = [ "src/hci.rs" ] - all_dependent_configs = [ ":rust_shim_config" ] - deps = [ ":cxxlibheader" ] -} - -cxxbridge_cc("hci_bridge_code") { - sources = [ "src/hci.rs" ] - deps = [ ":hci_bridge_header" ] - configs = [ "//bt/gd:gd_defaults" ] -} - cxxbridge_header("message_loop_thread_bridge_header") { sources = [ "src/message_loop_thread.rs" ] all_dependent_configs = [ ":rust_shim_config" ] @@ -75,27 +56,13 @@ cxxbridge_cc("message_loop_thread_bridge_code") { configs = [ "//bt/gd:gd_defaults" ] } -cxxbridge_header("controller_bridge_header") { - sources = [ "src/controller.rs" ] - all_dependent_configs = [ ":rust_shim_config" ] - deps = [ ":cxxlibheader" ] -} - -cxxbridge_cc("controller_bridge_code") { - sources = [ "src/controller.rs" ] - deps = [ ":controller_bridge_header" ] - configs = [ "//bt/gd:gd_defaults" ] -} - cxxbridge_libheader("cxxlibheader") { deps = [] } static_library("libbluetooth_rust_interop") { deps = [ - ":controller_bridge_code", ":cxxlibheader", - ":hci_bridge_code", ":init_flags_bridge_code", ":message_loop_thread_bridge_code", ":shim_bridge_code", diff --git a/system/gd/rust/shim/callbacks/callbacks.h b/system/gd/rust/shim/callbacks/callbacks.h index a8e3dd4f46aa0014d089393e1bec6800a6a961c1..98d9f81b6bc78dbba1245d3a54a050dff3f76760 100644 --- a/system/gd/rust/shim/callbacks/callbacks.h +++ b/system/gd/rust/shim/callbacks/callbacks.h @@ -63,11 +63,11 @@ class OnceClosure { base::OnceClosure* closure_; }; -using u8SliceCallback = TrampolineCallback<::rust::Slice<uint8_t>>; -using u8SliceOnceCallback = TrampolineOnceCallback<::rust::Slice<uint8_t>>; +using u8SliceCallback = TrampolineCallback<::rust::Slice<const uint8_t>>; +using u8SliceOnceCallback = TrampolineOnceCallback<::rust::Slice<const uint8_t>>; } // namespace rust } // namespace shim } // namespace bluetooth -#include "src/hci.rs.h" +#include "src/bridge.rs.h" diff --git a/system/gd/rust/shim/src/bridge.rs b/system/gd/rust/shim/src/bridge.rs new file mode 100644 index 0000000000000000000000000000000000000000..96b35cce3e8b13e760154e7f946381d50954879a --- /dev/null +++ b/system/gd/rust/shim/src/bridge.rs @@ -0,0 +1,112 @@ +//! Merged bridge + +pub use crate::controller::*; +pub use crate::hci::*; +pub use crate::stack::*; + +#[cxx::bridge(namespace = bluetooth::shim::rust)] +pub mod ffi { + extern "Rust" { + type Stack; + type Hci; + type Controller; + + // Stack + fn stack_create() -> Box<Stack>; + fn stack_start(stack: &mut Stack); + fn stack_stop(stack: &mut Stack); + + fn get_hci(stack: &mut Stack) -> Box<Hci>; + fn get_controller(stack: &mut Stack) -> Box<Controller>; + + // HCI + fn hci_set_acl_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); + fn hci_set_evt_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); + fn hci_set_le_evt_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); + + fn hci_send_command(hci: &mut Hci, data: &[u8], callback: UniquePtr<u8SliceOnceCallback>); + fn hci_send_acl(hci: &mut Hci, data: &[u8]); + fn hci_register_event(hci: &mut Hci, event: u8); + fn hci_register_le_event(hci: &mut Hci, subevent: u8); + + // Controller + fn controller_supports_simple_pairing(c: &Controller) -> bool; + fn controller_supports_secure_connections(c: &Controller) -> bool; + fn controller_supports_simultaneous_le_bredr(c: &Controller) -> bool; + fn controller_supports_interlaced_inquiry_scan(c: &Controller) -> bool; + fn controller_supports_rssi_with_inquiry_results(c: &Controller) -> bool; + fn controller_supports_extended_inquiry_response(c: &Controller) -> bool; + fn controller_supports_role_switch(c: &Controller) -> bool; + fn controller_supports_three_slot_packets(c: &Controller) -> bool; + fn controller_supports_five_slot_packets(c: &Controller) -> bool; + fn controller_supports_classic_2m_phy(c: &Controller) -> bool; + fn controller_supports_classic_3m_phy(c: &Controller) -> bool; + fn controller_supports_three_slot_edr_packets(c: &Controller) -> bool; + fn controller_supports_five_slot_edr_packets(c: &Controller) -> bool; + fn controller_supports_sco(c: &Controller) -> bool; + fn controller_supports_hv2_packets(c: &Controller) -> bool; + fn controller_supports_hv3_packets(c: &Controller) -> bool; + fn controller_supports_ev3_packets(c: &Controller) -> bool; + fn controller_supports_ev4_packets(c: &Controller) -> bool; + fn controller_supports_ev5_packets(c: &Controller) -> bool; + fn controller_supports_esco_2m_phy(c: &Controller) -> bool; + fn controller_supports_esco_3m_phy(c: &Controller) -> bool; + fn controller_supports_three_slot_esco_edr_packets(c: &Controller) -> bool; + fn controller_supports_hold_mode(c: &Controller) -> bool; + fn controller_supports_sniff_mode(c: &Controller) -> bool; + fn controller_supports_park_mode(c: &Controller) -> bool; + fn controller_supports_non_flushable_pb(c: &Controller) -> bool; + fn controller_supports_sniff_subrating(c: &Controller) -> bool; + fn controller_supports_encryption_pause(c: &Controller) -> bool; + fn controller_supports_ble(c: &Controller) -> bool; + + fn controller_supports_privacy(c: &Controller) -> bool; + fn controller_supports_packet_extension(c: &Controller) -> bool; + fn controller_supports_connection_parameters_request(c: &Controller) -> bool; + fn controller_supports_ble_2m_phy(c: &Controller) -> bool; + fn controller_supports_ble_coded_phy(c: &Controller) -> bool; + fn controller_supports_extended_advertising(c: &Controller) -> bool; + fn controller_supports_periodic_advertising(c: &Controller) -> bool; + fn controller_supports_peripheral_initiated_feature_exchange(c: &Controller) -> bool; + fn controller_supports_connection_parameter_request(c: &Controller) -> bool; + fn controller_supports_periodic_advertising_sync_transfer_sender(c: &Controller) -> bool; + fn controller_supports_periodic_advertising_sync_transfer_recipient(c: &Controller) + -> bool; + fn controller_supports_connected_iso_stream_central(c: &Controller) -> bool; + fn controller_supports_connected_iso_stream_peripheral(c: &Controller) -> bool; + fn controller_supports_iso_broadcaster(c: &Controller) -> bool; + fn controller_supports_synchronized_receiver(c: &Controller) -> bool; + + fn controller_supports_reading_remote_extended_features(c: &Controller) -> bool; + fn controller_supports_enhanced_setup_synchronous_connection(c: &Controller) -> bool; + fn controller_supports_enhanced_accept_synchronous_connection(c: &Controller) -> bool; + fn controller_supports_ble_set_privacy_mode(c: &Controller) -> bool; + + fn controller_get_acl_buffer_length(c: &Controller) -> u16; + fn controller_get_le_buffer_length(c: &Controller) -> u16; + fn controller_get_iso_buffer_length(c: &Controller) -> u16; + fn controller_get_le_suggested_default_data_length(c: &Controller) -> u16; + fn controller_get_le_maximum_tx_data_length(c: &Controller) -> u16; + fn controller_get_le_max_advertising_data_length(c: &Controller) -> u16; + fn controller_get_le_supported_advertising_sets(c: &Controller) -> u8; + fn controller_get_le_periodic_advertiser_list_size(c: &Controller) -> u8; + fn controller_get_acl_buffers(c: &Controller) -> u16; + fn controller_get_le_buffers(c: &Controller) -> u8; + fn controller_get_iso_buffers(c: &Controller) -> u8; + fn controller_get_le_connect_list_size(c: &Controller) -> u8; + fn controller_get_le_resolving_list_size(c: &Controller) -> u8; + fn controller_get_le_supported_states(c: &Controller) -> u64; + + fn controller_get_address(c: &Controller) -> String; + } + + unsafe extern "C++" { + include!("callbacks/callbacks.h"); + + type u8SliceCallback; + fn Run(self: &u8SliceCallback, data: &[u8]); + + type u8SliceOnceCallback; + fn Run(self: &u8SliceOnceCallback, data: &[u8]); + } +} diff --git a/system/gd/rust/shim/src/controller.rs b/system/gd/rust/shim/src/controller.rs index 70036eba114e0e21180c3fbee26411a08ee1c468..fbb46e14c8aaebb838c4cd6db3a058c3cb38bee2 100644 --- a/system/gd/rust/shim/src/controller.rs +++ b/system/gd/rust/shim/src/controller.rs @@ -3,91 +3,23 @@ use bt_hci::ControllerExports; use bt_packets::hci::OpCode; use paste::paste; +use std::ops::Deref; use std::sync::Arc; -#[cxx::bridge(namespace = bluetooth::shim::rust)] -mod ffi { - extern "Rust" { - type Controller; - - fn controller_supports_simple_pairing(c: &Controller) -> bool; - fn controller_supports_secure_connections(c: &Controller) -> bool; - fn controller_supports_simultaneous_le_bredr(c: &Controller) -> bool; - fn controller_supports_interlaced_inquiry_scan(c: &Controller) -> bool; - fn controller_supports_rssi_with_inquiry_results(c: &Controller) -> bool; - fn controller_supports_extended_inquiry_response(c: &Controller) -> bool; - fn controller_supports_role_switch(c: &Controller) -> bool; - fn controller_supports_three_slot_packets(c: &Controller) -> bool; - fn controller_supports_five_slot_packets(c: &Controller) -> bool; - fn controller_supports_classic_2m_phy(c: &Controller) -> bool; - fn controller_supports_classic_3m_phy(c: &Controller) -> bool; - fn controller_supports_three_slot_edr_packets(c: &Controller) -> bool; - fn controller_supports_five_slot_edr_packets(c: &Controller) -> bool; - fn controller_supports_sco(c: &Controller) -> bool; - fn controller_supports_hv2_packets(c: &Controller) -> bool; - fn controller_supports_hv3_packets(c: &Controller) -> bool; - fn controller_supports_ev3_packets(c: &Controller) -> bool; - fn controller_supports_ev4_packets(c: &Controller) -> bool; - fn controller_supports_ev5_packets(c: &Controller) -> bool; - fn controller_supports_esco_2m_phy(c: &Controller) -> bool; - fn controller_supports_esco_3m_phy(c: &Controller) -> bool; - fn controller_supports_three_slot_esco_edr_packets(c: &Controller) -> bool; - fn controller_supports_hold_mode(c: &Controller) -> bool; - fn controller_supports_sniff_mode(c: &Controller) -> bool; - fn controller_supports_park_mode(c: &Controller) -> bool; - fn controller_supports_non_flushable_pb(c: &Controller) -> bool; - fn controller_supports_sniff_subrating(c: &Controller) -> bool; - fn controller_supports_encryption_pause(c: &Controller) -> bool; - fn controller_supports_ble(c: &Controller) -> bool; - - fn controller_supports_privacy(c: &Controller) -> bool; - fn controller_supports_packet_extension(c: &Controller) -> bool; - fn controller_supports_connection_parameters_request(c: &Controller) -> bool; - fn controller_supports_ble_2m_phy(c: &Controller) -> bool; - fn controller_supports_ble_coded_phy(c: &Controller) -> bool; - fn controller_supports_extended_advertising(c: &Controller) -> bool; - fn controller_supports_periodic_advertising(c: &Controller) -> bool; - fn controller_supports_peripheral_initiated_feature_exchange(c: &Controller) -> bool; - fn controller_supports_connection_parameter_request(c: &Controller) -> bool; - fn controller_supports_periodic_advertising_sync_transfer_sender(c: &Controller) -> bool; - fn controller_supports_periodic_advertising_sync_transfer_recipient(c: &Controller) - -> bool; - fn controller_supports_connected_iso_stream_central(c: &Controller) -> bool; - fn controller_supports_connected_iso_stream_peripheral(c: &Controller) -> bool; - fn controller_supports_iso_broadcaster(c: &Controller) -> bool; - fn controller_supports_synchronized_receiver(c: &Controller) -> bool; - - fn controller_supports_reading_remote_extended_features(c: &Controller) -> bool; - fn controller_supports_enhanced_setup_synchronous_connection(c: &Controller) -> bool; - fn controller_supports_enhanced_accept_synchronous_connection(c: &Controller) -> bool; - fn controller_supports_ble_set_privacy_mode(c: &Controller) -> bool; - - fn controller_get_acl_buffer_length(c: &Controller) -> u16; - fn controller_get_le_buffer_length(c: &Controller) -> u16; - fn controller_get_iso_buffer_length(c: &Controller) -> u16; - fn controller_get_le_suggested_default_data_length(c: &Controller) -> u16; - fn controller_get_le_maximum_tx_data_length(c: &Controller) -> u16; - fn controller_get_le_max_advertising_data_length(c: &Controller) -> u16; - fn controller_get_le_supported_advertising_sets(c: &Controller) -> u8; - fn controller_get_le_periodic_advertiser_list_size(c: &Controller) -> u8; - fn controller_get_acl_buffers(c: &Controller) -> u16; - fn controller_get_le_buffers(c: &Controller) -> u8; - fn controller_get_iso_buffers(c: &Controller) -> u8; - fn controller_get_le_connect_list_size(c: &Controller) -> u8; - fn controller_get_le_resolving_list_size(c: &Controller) -> u8; - fn controller_get_le_supported_states(c: &Controller) -> u64; - - fn controller_get_address(c: &Controller) -> String; +#[derive(Clone)] +pub struct Controller(pub Arc<ControllerExports>); +impl Deref for Controller { + type Target = Arc<ControllerExports>; + fn deref(&self) -> &Self::Target { + &self.0 } } -pub type Controller = Arc<ControllerExports>; - macro_rules! feature_getters { ($($id:ident),*) => { paste! { $( - fn [<controller_supports_ $id>](c: &Controller) -> bool { + pub fn [<controller_supports_ $id>](c: &Controller) -> bool { c.features.$id } )* @@ -131,7 +63,7 @@ macro_rules! le_feature_getters { ($($id:ident),*) => { paste! { $( - fn [<controller_supports_ $id>](c: &Controller) -> bool { + pub fn [<controller_supports_ $id>](c: &Controller) -> bool { c.le_features.$id } )* @@ -161,7 +93,7 @@ macro_rules! opcode_getters { ($($id:ident => $opcode:path),*) => { paste! { $( - fn [<controller_supports_ $id>](c: &Controller) -> bool { + pub fn [<controller_supports_ $id>](c: &Controller) -> bool { c.commands.is_supported($opcode) } )* @@ -180,7 +112,7 @@ macro_rules! field_getters { ($($id:ident : $type:ty),*) => { paste! { $( - fn [<controller_get_ $id>](c: &Controller) -> $type { + pub fn [<controller_get_ $id>](c: &Controller) -> $type { c.$id } )* @@ -204,10 +136,10 @@ field_getters! { le_supported_states: u64 } -fn controller_get_le_maximum_tx_data_length(c: &Controller) -> u16 { +pub fn controller_get_le_maximum_tx_data_length(c: &Controller) -> u16 { c.le_max_data_length.supported_max_tx_octets } -fn controller_get_address(c: &Controller) -> String { +pub fn controller_get_address(c: &Controller) -> String { c.address.to_string() } diff --git a/system/gd/rust/shim/src/hci.rs b/system/gd/rust/shim/src/hci.rs index 902a3f933db76f68fca2e1763694af7d12182bef..e0764c8a17b527568a9e6e250367bde5dbfb2ed7 100644 --- a/system/gd/rust/shim/src/hci.rs +++ b/system/gd/rust/shim/src/hci.rs @@ -1,37 +1,12 @@ //! Hci shim +use crate::bridge::ffi; use bt_facade_helpers::U8SliceRunnable; use bt_hci::facade::HciFacadeService; use bt_packets::hci::{AclPacket, CommandPacket, Packet}; use std::sync::Arc; use tokio::runtime::Runtime; -#[cxx::bridge(namespace = bluetooth::shim::rust)] -mod ffi { - extern "C" { - include!("callbacks/callbacks.h"); - - type u8SliceCallback; - fn Run(self: &u8SliceCallback, data: &[u8]); - - type u8SliceOnceCallback; - fn Run(self: &u8SliceOnceCallback, data: &[u8]); - } - - extern "Rust" { - type Hci; - - fn hci_set_acl_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); - fn hci_set_evt_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); - fn hci_set_le_evt_callback(hci: &mut Hci, callback: UniquePtr<u8SliceCallback>); - - fn hci_send_command(hci: &mut Hci, data: &[u8], callback: UniquePtr<u8SliceOnceCallback>); - fn hci_send_acl(hci: &mut Hci, data: &[u8]); - fn hci_register_event(hci: &mut Hci, event: u8); - fn hci_register_le_event(hci: &mut Hci, subevent: u8); - } -} - // we take ownership when we get the callbacks unsafe impl Send for ffi::u8SliceCallback {} unsafe impl Send for ffi::u8SliceOnceCallback {} diff --git a/system/gd/rust/shim/src/lib.rs b/system/gd/rust/shim/src/lib.rs index afe4e45e74a6a5675799e0516cda61fdda3e4f91..a87fb258d796d1c1006babbf0b39c406a9ce8660 100644 --- a/system/gd/rust/shim/src/lib.rs +++ b/system/gd/rust/shim/src/lib.rs @@ -2,6 +2,7 @@ #[macro_use] extern crate lazy_static; +mod bridge; mod controller; mod hci; mod init_flags; diff --git a/system/gd/rust/shim/src/message_loop_thread.rs b/system/gd/rust/shim/src/message_loop_thread.rs index df32e6d12ce57edbb6835023ff7ba17cd3e9f9cd..107c85510d7b7dce25e37b7751dab4b75f40f0b0 100644 --- a/system/gd/rust/shim/src/message_loop_thread.rs +++ b/system/gd/rust/shim/src/message_loop_thread.rs @@ -9,7 +9,7 @@ use tokio::sync::mpsc::{unbounded_channel, UnboundedSender}; #[cxx::bridge(namespace = bluetooth::shim::rust)] mod ffi { - extern "C" { + unsafe extern "C++" { include!("callbacks/callbacks.h"); type OnceClosure; diff --git a/system/gd/rust/shim/src/stack.rs b/system/gd/rust/shim/src/stack.rs index 2dc77d2ce20eed87f520416720a4dfc526f13fe3..5c19ca4865059d90862abe52ad55464016332c77 100644 --- a/system/gd/rust/shim/src/stack.rs +++ b/system/gd/rust/shim/src/stack.rs @@ -3,10 +3,26 @@ use crate::controller::Controller; use crate::hci::Hci; use bt_common::init_flags; -use bt_main::Stack; +use bt_hci::ControllerExports; +use std::ops::{Deref, DerefMut}; use std::sync::Arc; use tokio::runtime::{Builder, Runtime}; +pub struct Stack(bt_main::Stack); + +impl Deref for Stack { + type Target = bt_main::Stack; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Stack { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + lazy_static! { pub static ref RUNTIME: Arc<Runtime> = Arc::new( Builder::new_multi_thread() @@ -18,34 +34,15 @@ lazy_static! { ); } -#[cxx::bridge(namespace = bluetooth::shim::rust)] -mod ffi { - extern "Rust" { - // TODO(abps) - https://github.com/dtolnay/cxx/issues/496 - // Externing non-local types results in E0117 errors and that breaks - // building with CXX > 1.0. - type Stack; - type Hci; - type Controller; - - fn stack_create() -> Box<Stack>; - fn stack_start(stack: &mut Stack); - fn stack_stop(stack: &mut Stack); - - fn get_hci(stack: &mut Stack) -> Box<Hci>; - fn get_controller(stack: &mut Stack) -> Box<Controller>; - } -} - pub fn stack_create() -> Box<Stack> { assert!(init_flags::gd_rust_is_enabled()); let local_rt = RUNTIME.clone(); RUNTIME.block_on(async move { - let stack = Stack::new(local_rt).await; + let stack = bt_main::Stack::new(local_rt).await; stack.use_default_snoop().await; - Box::new(stack) + Box::new(Stack(stack)) }) } @@ -73,5 +70,5 @@ pub fn get_controller(stack: &mut Stack) -> Box<Controller> { assert!(init_flags::gd_rust_is_enabled()); assert!(init_flags::gd_controller_is_enabled()); - Box::new(stack.get_blocking::<Controller>()) + Box::new(Controller(stack.get_blocking::<Arc<ControllerExports>>())) } diff --git a/system/main/shim/controller.cc b/system/main/shim/controller.cc index 487f06c6b676836156002b4a464b5772ddffa649..91dcee4e313de0ced1af23d7d786b10295df2757 100644 --- a/system/main/shim/controller.cc +++ b/system/main/shim/controller.cc @@ -26,7 +26,7 @@ #include "osi/include/log.h" #include "hci/controller.h" -#include "src/controller.rs.h" +#include "src/bridge.rs.h" using ::bluetooth::common::init_flags::gd_rust_is_enabled; using ::bluetooth::shim::GetController; diff --git a/system/main/shim/hci_layer.cc b/system/main/shim/hci_layer.cc index bca7e3b7ae5dfe29276e3cf46e92ca9a1833004b..a45551fa29f6e83441d373da0823067777aa6de0 100644 --- a/system/main/shim/hci_layer.cc +++ b/system/main/shim/hci_layer.cc @@ -34,7 +34,7 @@ #include "osi/include/allocator.h" #include "osi/include/future.h" #include "packet/raw_builder.h" -#include "src/hci.rs.h" +#include "src/bridge.rs.h" #include "stack/include/bt_types.h" /** @@ -394,7 +394,7 @@ static void transmit_command(BT_HDR* command, } } -static void transmit_fragment(uint8_t* stream, size_t length) { +static void transmit_fragment(const uint8_t* stream, size_t length) { uint16_t handle_with_flags; STREAM_TO_UINT16(handle_with_flags, stream); auto pb_flag = static_cast<bluetooth::hci::PacketBoundaryFlag>( @@ -501,7 +501,7 @@ using bluetooth::shim::rust::u8SliceCallback; using bluetooth::shim::rust::u8SliceOnceCallback; static BT_HDR* WrapRustPacketAndCopy(uint16_t event, - ::rust::Slice<uint8_t>* data) { + ::rust::Slice<const uint8_t>* data) { size_t packet_size = data->length() + kBtHdrSize; BT_HDR* packet = reinterpret_cast<BT_HDR*>(osi_malloc(packet_size)); packet->offset = 0; @@ -512,7 +512,7 @@ static BT_HDR* WrapRustPacketAndCopy(uint16_t event, return packet; } -static void on_acl(::rust::Slice<uint8_t> data) { +static void on_acl(::rust::Slice<const uint8_t> data) { if (!send_data_upwards) { return; } @@ -520,7 +520,7 @@ static void on_acl(::rust::Slice<uint8_t> data) { packet_fragmenter->reassemble_and_dispatch(legacy_data); } -static void on_event(::rust::Slice<uint8_t> data) { +static void on_event(::rust::Slice<const uint8_t> data) { if (!send_data_upwards) { return; } @@ -530,7 +530,7 @@ static void on_event(::rust::Slice<uint8_t> data) { void OnRustTransmitPacketCommandComplete(command_complete_cb complete_callback, void* context, - ::rust::Slice<uint8_t> data) { + ::rust::Slice<const uint8_t> data) { BT_HDR* response = WrapRustPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &data); complete_callback(response, context); } @@ -538,7 +538,7 @@ void OnRustTransmitPacketCommandComplete(command_complete_cb complete_callback, void OnRustTransmitPacketStatus(command_status_cb status_callback, void* context, std::unique_ptr<OsiObject> command, - ::rust::Slice<uint8_t> data) { + ::rust::Slice<const uint8_t> data) { ASSERT(data.length() >= 3); uint8_t status = data.data()[2]; status_callback(status, static_cast<BT_HDR*>(command->Release()), context); @@ -548,7 +548,7 @@ static void transmit_command(BT_HDR* command, command_complete_cb complete_callback, command_status_cb status_callback, void* context) { CHECK(command != nullptr); - uint8_t* data = command->data + command->offset; + const uint8_t* data = command->data + command->offset; size_t len = command->len; CHECK(len >= (kCommandOpcodeSize + kCommandLengthSize)); @@ -576,7 +576,7 @@ static void transmit_command(BT_HDR* command, } } -static void transmit_fragment(uint8_t* stream, size_t length) { +static void transmit_fragment(const uint8_t* stream, size_t length) { bluetooth::shim::rust::hci_send_acl( **bluetooth::shim::Stack::Stack::GetInstance()->GetRustHci(), ::rust::Slice(stream, length)); @@ -654,7 +654,7 @@ static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) { (packet->event & MSG_EVT_MASK) != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished; - uint8_t* stream = packet->data + packet->offset; + const uint8_t* stream = packet->data + packet->offset; size_t length = packet->len; if (bluetooth::common::init_flags::gd_rust_is_enabled()) { rust::transmit_fragment(stream, length); diff --git a/system/main/shim/stack.h b/system/main/shim/stack.h index a981e632c97b85c790132c57b422cc90fffd684a..948d13bc891bb444093a213663d4742031d449a7 100644 --- a/system/main/shim/stack.h +++ b/system/main/shim/stack.h @@ -27,7 +27,7 @@ #include "gd/os/thread.h" #include "gd/os/utils.h" #include "gd/stack_manager.h" -#include "src/stack.rs.h" +#include "src/bridge.rs.h" // The shim layer implementation on the Gd stack side. namespace bluetooth {