cflags: [
"-DBUILDCFG",
],
-
}
// btif unit tests for target
enabled: false,
},
},
+ generated_headers: [
+ "libbt_common_bridge_header",
+ ],
}
// Enables code coverage for a set of source files. Must be combined with
#include "common/strings.h"
#include "os/log.h"
-#include "src/init_flags.rs.h"
namespace bluetooth {
namespace common {
-bool InitFlags::btaa_hci_log_enabled = false;
-bool InitFlags::gd_core_enabled = false;
-bool InitFlags::gd_advertising_enabled = false;
-bool InitFlags::gd_security_enabled = false;
-bool InitFlags::gd_acl_enabled = false;
-bool InitFlags::gd_l2cap_enabled = false;
-bool InitFlags::gd_hci_enabled = false;
-bool InitFlags::gd_controller_enabled = false;
-bool InitFlags::gatt_robust_caching_enabled = false;
bool InitFlags::logging_debug_enabled_for_all = false;
std::unordered_map<std::string, bool> InitFlags::logging_debug_explicit_tag_settings = {};
}
void InitFlags::Load(const char** flags) {
- rust::Vec<rust::String> rusted_flags = rust::Vec<rust::String>();
- while (flags != nullptr && *flags != nullptr) {
- rusted_flags.push_back(rust::String(*flags));
- flags++;
- }
- init_flags_load(std::move(rusted_flags));
-
SetAll(false);
while (flags != nullptr && *flags != nullptr) {
std::string flag_element = *flags;
auto flag_pair = StringSplit(flag_element, "=", 2);
if (flag_pair.size() != 2) {
- LOG_ERROR("Bad flag %s, must be in <FLAG>=<VALUE> format", flag_element.c_str());
flags++;
continue;
}
- ParseBoolFlag(flag_pair, "INIT_gd_core", &gd_core_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_advertising", &gd_advertising_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_security", &gd_security_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_acl", &gd_acl_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_l2cap", &gd_l2cap_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_hci", &gd_hci_enabled);
- ParseBoolFlag(flag_pair, "INIT_gd_controller", &gd_controller_enabled);
- ParseBoolFlag(flag_pair, "INIT_gatt_robust_caching", &gatt_robust_caching_enabled);
ParseBoolFlag(flag_pair, "INIT_logging_debug_enabled_for_all", &logging_debug_enabled_for_all);
- ParseBoolFlag(flag_pair, "INIT_btaa_hci", &btaa_hci_log_enabled);
if ("INIT_logging_debug_enabled_for_tags" == flag_pair[0]) {
auto tags = StringSplit(flag_pair[1], ",");
for (const auto& tag : tags) {
flags++;
}
- if (gd_core_enabled && !gd_security_enabled) {
- gd_security_enabled = true;
- }
- if (gd_security_enabled && !gd_acl_enabled) {
- gd_acl_enabled = true;
- }
- if (gd_acl_enabled && !gd_controller_enabled) {
- gd_controller_enabled = true;
- }
- if (gd_l2cap_enabled) {
- gd_acl_enabled = false;
- gd_hci_enabled = true;
- }
- if (gd_controller_enabled && !gd_hci_enabled) {
- gd_hci_enabled = true;
- }
-
std::vector<std::string> logging_debug_enabled_tags;
std::vector<std::string> logging_debug_disabled_tags;
for (const auto& tag_setting : logging_debug_explicit_tag_settings) {
}
}
- LOG_INFO(
- "Flags loaded: gd_advertising_enabled=%s, gd_security_enabled=%s, gd_acl_enabled=%s, gd_hci_enabled=%s, "
- "gd_controller_enabled=%s, gd_core_enabled=%s, logging_debug_enabled_for_all=%s, "
- "logging_debug_enabled_tags=%s, logging_debug_disabled_tags=%s, btaa_hci_log_enabled=%s",
- ToString(gd_advertising_enabled).c_str(),
- ToString(gd_security_enabled).c_str(),
- ToString(gd_acl_enabled).c_str(),
- ToString(gd_hci_enabled).c_str(),
- ToString(gd_controller_enabled).c_str(),
- ToString(gd_core_enabled).c_str(),
- ToString(logging_debug_enabled_for_all).c_str(),
- StringJoin(logging_debug_enabled_tags, ",").c_str(),
- StringJoin(logging_debug_disabled_tags, ",").c_str(),
- ToString(btaa_hci_log_enabled).c_str());
+ rust::Vec<rust::String> rusted_flags = rust::Vec<rust::String>();
+ while (flags != nullptr && *flags != nullptr) {
+ rusted_flags.push_back(rust::String(*flags));
+ flags++;
+ }
+ init_flags::load(std::move(rusted_flags));
}
void InitFlags::SetAll(bool value) {
- gd_core_enabled = value;
- gd_advertising_enabled = value;
- gd_acl_enabled = value;
- gd_security_enabled = value;
- gd_controller_enabled = value;
- gd_hci_enabled = value;
- gatt_robust_caching_enabled = value;
logging_debug_enabled_for_all = value;
logging_debug_explicit_tag_settings.clear();
}
void InitFlags::SetAllForTesting() {
+ init_flags::set_all_for_testing();
SetAll(true);
}
#include <string>
#include <unordered_map>
+#include "src/init_flags.rs.h"
namespace bluetooth {
namespace common {
public:
static void Load(const char** flags);
- static bool GdAdvertisingEnabled() {
- return gd_advertising_enabled;
- }
-
- static bool GdSecurityEnabled() {
- return gd_security_enabled;
- }
-
- static bool GdAclEnabled() {
- return gd_acl_enabled;
- }
-
- static bool GdHciEnabled() {
- return gd_hci_enabled;
- }
-
- static bool GdControllerEnabled() {
- return gd_controller_enabled;
- }
-
- static bool GdL2capEnabled() {
- return gd_l2cap_enabled;
- }
-
- static bool GdCoreEnabled() {
- return gd_core_enabled;
- }
-
- static bool GattRobustCachingEnabled() {
- return gatt_robust_caching_enabled;
- }
-
inline static bool IsDebugLoggingEnabledForTag(const std::string& tag) {
auto tag_setting = logging_debug_explicit_tag_settings.find(tag);
if (tag_setting != logging_debug_explicit_tag_settings.end()) {
return logging_debug_enabled_for_all;
}
- static bool BtaaHciLogEnabled() {
- return btaa_hci_log_enabled;
- }
-
static void SetAllForTesting();
private:
static void SetAll(bool value);
- static bool gd_advertising_enabled;
- static bool gd_security_enabled;
- static bool gd_acl_enabled;
- static bool gd_hci_enabled;
- static bool gd_controller_enabled;
- static bool gd_l2cap_enabled;
- static bool gd_core_enabled;
- static bool gatt_robust_caching_enabled;
static bool logging_debug_enabled_for_all;
// save both log allow list and block list in the map to save hashing time
static std::unordered_map<std::string, bool> logging_debug_explicit_tag_settings;
- static bool btaa_hci_log_enabled;
};
} // namespace common
using bluetooth::common::InitFlags;
-TEST(InitFlagsTest, test_load_nullptr) {
- InitFlags::Load(nullptr);
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
-}
-
-TEST(InitFlagsTest, test_load_empty) {
- const char* input[] = {nullptr};
- InitFlags::Load(input);
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
-}
-
-TEST(InitFlagsTest, test_load_garbage) {
- const char* input[] = {"some random non-existent flag", nullptr};
- InitFlags::Load(input);
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
-}
-
-TEST(InitFlagsTest, test_load_core) {
- const char* input[] = {"INIT_gd_core=true", nullptr};
- InitFlags::Load(input);
- ASSERT_TRUE(InitFlags::GdCoreEnabled());
- ASSERT_TRUE(InitFlags::GdControllerEnabled());
- ASSERT_TRUE(InitFlags::GdHciEnabled());
- ASSERT_FALSE(InitFlags::BtaaHciLogEnabled());
-}
-
-TEST(InitFlagsTest, test_load_controller) {
- const char* input[] = {"INIT_gd_controller=true", nullptr};
- InitFlags::Load(input);
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
- ASSERT_TRUE(InitFlags::GdControllerEnabled());
- ASSERT_TRUE(InitFlags::GdHciEnabled());
- ASSERT_FALSE(InitFlags::BtaaHciLogEnabled());
-}
-
-TEST(InitFlagsTest, test_load_hci) {
- const char* input[] = {"INIT_gd_hci=true", nullptr};
- InitFlags::Load(input);
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
- ASSERT_FALSE(InitFlags::GdControllerEnabled());
- ASSERT_TRUE(InitFlags::GdHciEnabled());
- ASSERT_FALSE(InitFlags::BtaaHciLogEnabled());
-}
-
-TEST(InitFlagsTest, test_load_gatt_robust_caching) {
- const char* input[] = {"INIT_gatt_robust_caching=true", nullptr};
- InitFlags::Load(input);
- ASSERT_TRUE(InitFlags::GattRobustCachingEnabled());
-}
-
TEST(InitFlagsTest, test_enable_debug_logging_for_all) {
const char* input[] = {"INIT_logging_debug_enabled_for_all=true", nullptr};
InitFlags::Load(input);
ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForTag("Foo"));
ASSERT_FALSE(InitFlags::IsDebugLoggingEnabledForAll());
}
-
-TEST(InitFlagsTest, test_load_btaa_hci_log) {
- const char* input[] = {"INIT_btaa_hci=true", nullptr};
- InitFlags::Load(input);
- ASSERT_TRUE(InitFlags::BtaaHciLogEnabled());
- ASSERT_FALSE(InitFlags::GdCoreEnabled());
- ASSERT_FALSE(InitFlags::GdControllerEnabled());
- ASSERT_FALSE(InitFlags::GdHciEnabled());
-}
auto title = fb_builder->CreateString("----- Init Flags -----");
common::InitFlagsDataBuilder builder(*fb_builder);
builder.add_title(title);
- builder.add_gd_advertising_enabled(bluetooth::common::InitFlags::GdAdvertisingEnabled());
- builder.add_gd_security_enabled(bluetooth::common::InitFlags::GdSecurityEnabled());
- builder.add_gd_acl_enabled(bluetooth::common::InitFlags::GdAclEnabled());
- builder.add_gd_hci_enabled(bluetooth::common::InitFlags::GdHciEnabled());
- builder.add_gd_controller_enabled(bluetooth::common::InitFlags::GdControllerEnabled());
- builder.add_gd_core_enabled(bluetooth::common::InitFlags::GdCoreEnabled());
+ builder.add_gd_advertising_enabled(bluetooth::common::init_flags::gd_advertising_is_enabled());
+ builder.add_gd_security_enabled(bluetooth::common::init_flags::gd_security_is_enabled());
+ builder.add_gd_acl_enabled(bluetooth::common::init_flags::gd_acl_is_enabled());
+ builder.add_gd_hci_enabled(bluetooth::common::init_flags::gd_hci_is_enabled());
+ builder.add_gd_controller_enabled(bluetooth::common::init_flags::gd_controller_is_enabled());
+ builder.add_gd_core_enabled(bluetooth::common::init_flags::gd_core_is_enabled());
return builder.Finish();
}
void Start(hci::HciLayer* hci) {
hci_ = hci;
Handler* handler = module_.GetHandler();
- if (common::InitFlags::GdAclEnabled() || common::InitFlags::GdL2capEnabled()) {
+ if (common::init_flags::gd_acl_is_enabled() || common::init_flags::gd_l2cap_is_enabled()) {
hci_->RegisterEventHandler(
EventCode::NUMBER_OF_COMPLETED_PACKETS, handler->BindOn(this, &Controller::impl::NumberOfCompletedPackets));
}
}
void Stop() {
- if (bluetooth::common::InitFlags::GdCoreEnabled()) {
+ if (bluetooth::common::init_flags::gd_core_is_enabled()) {
hci_->UnregisterEventHandler(EventCode::NUMBER_OF_COMPLETED_PACKETS);
}
hci_ = nullptr;
RegisterEventHandler(EventCode::COMMAND_COMPLETE, handler->BindOn(impl_, &impl::on_command_complete));
RegisterEventHandler(EventCode::COMMAND_STATUS, handler->BindOn(impl_, &impl::on_command_status));
RegisterLeMetaEventHandler(handler->BindOn(impl_, &impl::on_le_meta_event));
- if (bluetooth::common::InitFlags::GdAclEnabled() || bluetooth::common::InitFlags::GdL2capEnabled()) {
+ if (bluetooth::common::init_flags::gd_acl_is_enabled() || bluetooth::common::init_flags::gd_l2cap_is_enabled()) {
RegisterEventHandler(
EventCode::DISCONNECTION_COMPLETE, handler->BindOn(this, &HciLayer::on_disconnection_complete));
RegisterEventHandler(
} else if (
address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS ||
address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
- if (bluetooth::common::InitFlags::GdAclEnabled()) {
+ if (bluetooth::common::init_flags::gd_acl_is_enabled()) {
if (registered_clients_.size() == 1) {
schedule_rotate_random_address();
}
-rust_library {
- name: "libbt_common",
+rust_defaults {
+ name: "libbt_common_defaults",
+ stem: "libbt_common",
crate_name: "bt_common",
srcs: ["src/lib.rs"],
edition: "2018",
],
},
},
+ proc_macros: [
+ "libpaste",
+ ],
host_supported: true,
}
+rust_library {
+ name: "libbt_common",
+ defaults: ["libbt_common_defaults"],
+}
+
rust_ffi_static {
name: "libbt_common_ffi",
- stem: "libbt_common",
- crate_name: "bt_common",
- srcs: ["src/lib.rs"],
- edition: "2018",
- rustlibs: [
- "libtokio",
- "libnix",
- "liblog_rust",
- "libcxx",
- ],
- target: {
- android: {
- rustlibs: [
- "libandroid_logger",
- ],
- },
- host: {
- rustlibs: [
- "libenv_logger",
- ],
- },
- },
- host_supported: true,
+ defaults: ["libbt_common_defaults"],
}
rust_test_host {
-use log::error;
+use log::{error, info};
+use paste::paste;
+use std::sync::Mutex;
-#[cxx::bridge(namespace = bluetooth::common)]
+#[cxx::bridge(namespace = bluetooth::common::init_flags)]
mod ffi {
extern "Rust" {
- fn init_flags_load(flags: Vec<String>);
+ fn load(flags: Vec<String>);
+ fn set_all_for_testing();
+
+ fn gd_core_is_enabled() -> bool;
+ fn gd_security_is_enabled() -> bool;
+ fn gd_advertising_is_enabled() -> bool;
+ fn gd_acl_is_enabled() -> bool;
+ fn gd_l2cap_is_enabled() -> bool;
+ fn gd_hci_is_enabled() -> bool;
+ fn gd_controller_is_enabled() -> bool;
+ fn gatt_robust_caching_is_enabled() -> bool;
+ fn btaa_hci_is_enabled() -> bool;
}
}
-fn init_flags_load(flags: Vec<String>) {
- crate::init_logging();
+macro_rules! init_flags {
+ (flags: { $($flag:ident),* }, dependencies: { $($parent:ident => $child:ident),* }) => {
+ #[derive(Default)]
+ struct InitFlags {
+ $($flag: bool,)*
+ }
+
+ pub fn set_all_for_testing() {
+ *FLAGS.lock().unwrap() = InitFlags { $($flag: true,)* };
+ }
+
+ impl InitFlags {
+ fn parse(flags: Vec<String>) -> Self {
+ $(let mut $flag = false;)*
+
+ for flag in flags {
+ let values: Vec<&str> = flag.split("=").collect();
+ if values.len() != 2 {
+ error!("Bad flag {}, must be in <FLAG>=<VALUE> format", flag);
+ continue;
+ }
+
+ match values[0] {
+ $(concat!("INIT_", stringify!($flag)) => $flag = values[1].parse().unwrap_or(false),)*
+ _ => {}
+ }
+ }
+
+ Self { $($flag,)* }.reconcile()
+ }
+
+ fn reconcile(mut self) -> Self {
+ // Loop to ensure dependencies can be specified in any order
+ loop {
+ let mut any_change = false;
+ $(if self.$parent && !self.$child {
+ self.$child = true;
+ any_change = true;
+ })*
+
+ if !any_change {
+ break;
+ }
+ }
+
+ // TODO: acl should not be off if l2cap is on, but need to reconcile legacy code
+ if self.gd_l2cap {
+ self.gd_acl = false;
+ self.gd_hci = true;
+ }
+
+ self
+ }
- for flag in flags {
- error!("hello from rust: {}", flag);
+ fn log(&self) {
+ info!(concat!("Flags loaded: ", $(stringify!($flag), "={} ",)*), $(self.$flag,)*);
+ }
+ }
+
+ paste! {
+ $(
+ pub fn [<$flag _is_enabled>]() -> bool {
+ FLAGS.lock().unwrap().$flag
+ }
+ )*
+ }
+ };
+}
+
+init_flags!(
+ flags: {
+ gd_core,
+ gd_advertising,
+ gd_security,
+ gd_acl,
+ gd_l2cap,
+ gd_hci,
+ gd_controller,
+ gatt_robust_caching,
+ btaa_hci
+ },
+ dependencies: {
+ gd_core => gd_security,
+ gd_security => gd_acl,
+ gd_acl => gd_controller,
+ gd_controller => gd_hci
}
+);
+
+lazy_static! {
+ static ref FLAGS: Mutex<InitFlags> = Mutex::new(InitFlags::default());
+}
+
+fn load(flags: Vec<String>) {
+ crate::init_logging();
+
+ let flags = InitFlags::parse(flags);
+ flags.log();
+ *FLAGS.lock().unwrap() = flags;
}
+
+
//! Bluetooth common library
+#[macro_use]
+extern crate lazy_static;
/// Provides waking timer abstractions
pub mod time;
if (length && data_callback)
(*data_callback)(type, data, length, timestamp_us);
if (length && attribution_callback &&
- bluetooth::common::InitFlags::BtaaHciLogEnabled()) {
+ bluetooth::common::init_flags::btaa_hci_is_enabled()) {
(*attribution_callback)(type, data, length, timestamp_us);
}
}
// Register callback
bluetooth::shim::GetAdvertising()->RegisterAdvertisingCallback(this);
- if (!bluetooth::common::InitFlags::GdSecurityEnabled()) {
+ if (!bluetooth::common::init_flags::gd_security_is_enabled()) {
// Set private policy
auto address = bluetooth::shim::GetController()->GetMacAddress();
bluetooth::hci::AddressWithType address_with_type(
config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
}
- if (!bluetooth::common::InitFlags::GdSecurityEnabled()) {
+ if (!bluetooth::common::init_flags::gd_security_is_enabled()) {
// use public address for testing
config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
}
bool bluetooth::shim::is_gd_advertising_enabled() {
// TODO enable when module ready
- // return bluetooth::common::InitFlags::GdAdvertisingEnabled();
+ // return bluetooth::common::init_flags::gd_advertising_is_enabled();
return false;
}
bool bluetooth::shim::is_gd_security_enabled() {
- return bluetooth::common::InitFlags::GdSecurityEnabled();
+ return bluetooth::common::init_flags::gd_security_is_enabled();
}
bool bluetooth::shim::is_gd_acl_enabled() {
- return bluetooth::common::InitFlags::GdAclEnabled();
+ return bluetooth::common::init_flags::gd_acl_is_enabled();
}
bool bluetooth::shim::is_gd_hci_enabled() {
- return bluetooth::common::InitFlags::GdHciEnabled();
+ return bluetooth::common::init_flags::gd_hci_is_enabled();
}
bool bluetooth::shim::is_gd_controller_enabled() {
- return bluetooth::common::InitFlags::GdControllerEnabled();
+ return bluetooth::common::init_flags::gd_controller_is_enabled();
}
bool bluetooth::shim::is_gd_l2cap_enabled() {
- return bluetooth::common::InitFlags::GdL2capEnabled();
+ return bluetooth::common::init_flags::gd_l2cap_is_enabled();
}
bool bluetooth::shim::is_gd_shim_enabled() {
- return bluetooth::common::InitFlags::GdCoreEnabled();
+ return bluetooth::common::init_flags::gd_core_is_enabled();
}
bool bluetooth::shim::is_any_gd_enabled() {
- return bluetooth::common::InitFlags::GdHciEnabled();
+ return bluetooth::common::init_flags::gd_hci_is_enabled();
}
bool bluetooth::shim::is_gd_stack_started_up() {
ASSERT_LOG(!is_running_, "%s Gd stack already running", __func__);
LOG_INFO("%s Starting Gd stack", __func__);
ModuleList modules;
- if (common::InitFlags::GdHciEnabled()) {
+ if (common::init_flags::gd_hci_is_enabled()) {
modules.add<hal::HciHal>();
modules.add<hci::HciLayer>();
modules.add<storage::StorageModule>();
modules.add<shim::Dumpsys>();
}
- if (common::InitFlags::GdControllerEnabled()) {
+ if (common::init_flags::gd_controller_is_enabled()) {
modules.add<hci::Controller>();
}
- if (common::InitFlags::GdAclEnabled()) {
+ if (common::init_flags::gd_acl_is_enabled()) {
modules.add<hci::AclManager>();
}
- if (common::InitFlags::GdL2capEnabled()) {
+ if (common::init_flags::gd_l2cap_is_enabled()) {
modules.add<l2cap::classic::L2capClassicModule>();
modules.add<l2cap::le::L2capLeModule>();
}
- if (common::InitFlags::GdSecurityEnabled()) {
+ if (common::init_flags::gd_security_is_enabled()) {
modules.add<security::SecurityModule>();
}
- if (common::InitFlags::GdAdvertisingEnabled()) {
+ if (common::init_flags::gd_advertising_is_enabled()) {
modules.add<hci::LeAdvertisingManager>();
}
- if (common::InitFlags::GdCoreEnabled()) {
+ if (common::init_flags::gd_core_is_enabled()) {
modules.add<att::AttModule>();
modules.add<hci::LeScanningManager>();
modules.add<neighbor::ConnectabilityModule>();
// Make sure the leaf modules are started
ASSERT(stack_manager_.GetInstance<storage::StorageModule>() != nullptr);
ASSERT(stack_manager_.GetInstance<shim::Dumpsys>() != nullptr);
- if (common::InitFlags::GdCoreEnabled()) {
+ if (common::init_flags::gd_core_is_enabled()) {
btm_ = new Btm(stack_handler_,
stack_manager_.GetInstance<neighbor::InquiryModule>());
}
- if (common::InitFlags::GdAclEnabled()) {
- if (!common::InitFlags::GdCoreEnabled()) {
+ if (common::init_flags::gd_acl_is_enabled()) {
+ if (!common::init_flags::gd_core_is_enabled()) {
acl_ = new legacy::Acl(stack_handler_, legacy::GetAclInterface());
}
}
- if (!common::InitFlags::GdCoreEnabled()) {
+ if (!common::init_flags::gd_core_is_enabled()) {
bluetooth::shim::hci_on_reset_complete();
}
- if (common::InitFlags::GdAdvertisingEnabled()) {
+ if (common::init_flags::gd_advertising_is_enabled()) {
bluetooth::shim::init_advertising_manager();
}
- if (common::InitFlags::GdL2capEnabled() &&
- !common::InitFlags::GdCoreEnabled()) {
+ if (common::init_flags::gd_l2cap_is_enabled() &&
+ !common::init_flags::gd_core_is_enabled()) {
L2CA_UseLegacySecurityModule();
}
}
void Stack::Stop() {
std::lock_guard<std::recursive_mutex> lock(mutex_);
- if (!common::InitFlags::GdCoreEnabled()) {
+ if (!common::init_flags::gd_core_is_enabled()) {
bluetooth::shim::hci_on_shutting_down();
}
delete acl_;