rusty-gd: Add btsnoop config
Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost SimpleHalTest
Change-Id: Ibbce98d9e12355e0bef63ef62cfbac8098884775
diff --git a/system/gd/rust/common/src/sys_prop.rs b/system/gd/rust/common/src/sys_prop.rs
index 20b01f1..db0779f 100644
--- a/system/gd/rust/common/src/sys_prop.rs
+++ b/system/gd/rust/common/src/sys_prop.rs
@@ -27,3 +27,30 @@
pub fn get(_name: &str) -> Option<String> {
None
}
+
+/// Gets the specified property as a u32
+pub fn get_u32(name: &str) -> Option<u32> {
+ if let Some(value) = get(name) {
+ value.parse().ok()
+ } else {
+ None
+ }
+}
+
+/// Gets the specified property as a bool (logic follows libcutils/properties.cpp)
+pub fn get_bool(name: &str) -> Option<bool> {
+ if let Some(value) = get(name) {
+ match value.as_str() {
+ "0" | "n" | "no" | "false" | "off" => Some(false),
+ "1" | "y" | "yes" | "true" | "on" => Some(true),
+ _ => None
+ }
+ } else {
+ None
+ }
+}
+
+/// Gets whether the current build is debuggable
+pub fn get_debuggable() -> bool {
+ get_bool("ro.debuggable").unwrap_or(false)
+}
diff --git a/system/gd/rust/facade/src/lib.rs b/system/gd/rust/facade/src/lib.rs
index f15cb3d..ac6bc4d 100644
--- a/system/gd/rust/facade/src/lib.rs
+++ b/system/gd/rust/facade/src/lib.rs
@@ -35,10 +35,11 @@
rt: Arc<Runtime>,
grpc_port: u16,
rootcanal_port: Option<u16>,
+ snoop_path: Option<String>,
) -> grpcio::Service {
create_root_facade(Self {
rt: rt.clone(),
- manager: FacadeServiceManager::create(rt, grpc_port, rootcanal_port),
+ manager: FacadeServiceManager::create(rt, grpc_port, rootcanal_port, snoop_path),
})
}
}
@@ -121,7 +122,7 @@
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
impl FacadeServiceManager {
- fn create(rt: Arc<Runtime>, grpc_port: u16, rootcanal_port: Option<u16>) -> Self {
+ fn create(rt: Arc<Runtime>, grpc_port: u16, rootcanal_port: Option<u16>, snoop_path: Option<String>) -> Self {
let (tx, mut rx) = channel::<LifecycleCommand>(1);
let local_rt = rt.clone();
rt.spawn(async move {
@@ -131,6 +132,7 @@
LifecycleCommand::Start { req, done } => {
let stack = Stack::new(local_rt.clone()).await;
stack.set_rootcanal_port(rootcanal_port).await;
+ stack.configure_snoop(snoop_path.clone()).await;
server = Some(FacadeServer::start(stack, req, grpc_port).await);
done.send(()).unwrap();
}
diff --git a/system/gd/rust/facade/src/main.rs b/system/gd/rust/facade/src/main.rs
index ad2c3f7..a7227d4 100644
--- a/system/gd/rust/facade/src/main.rs
+++ b/system/gd/rust/facade/src/main.rs
@@ -12,12 +12,12 @@
use futures::executor::block_on;
use futures::stream::StreamExt;
use grpcio::*;
+use log::debug;
use nix::sys::signal;
use std::net::{IpAddr, Ipv4Addr, Shutdown, SocketAddr};
use std::sync::{Arc, Mutex};
use tokio::net::TcpStream;
use tokio::runtime::Runtime;
-use log::debug;
fn main() {
let sigint = install_sigint();
@@ -64,10 +64,14 @@
let grpc_port = value_t!(matches, "grpc-port", u16).unwrap();
let signal_port = value_t!(matches, "signal-port", u16).unwrap();
let rootcanal_port = value_t!(matches, "rootcanal-port", u16).ok();
-
let env = Arc::new(Environment::new(2));
let mut server = ServerBuilder::new(env)
- .register_service(RootFacadeService::create(rt, grpc_port, rootcanal_port))
+ .register_service(RootFacadeService::create(
+ rt,
+ grpc_port,
+ rootcanal_port,
+ matches.value_of("btsnoop").map(String::from),
+ ))
.bind("0.0.0.0", root_server_port)
.build()
.unwrap();
diff --git a/system/gd/rust/hal/src/lib.rs b/system/gd/rust/hal/src/lib.rs
index 75791e1..99f11d1 100644
--- a/system/gd/rust/hal/src/lib.rs
+++ b/system/gd/rust/hal/src/lib.rs
@@ -7,6 +7,7 @@
pub mod facade;
pub mod rootcanal_hal;
+pub mod snoop;
#[cfg(target_os = "android")]
mod hidl_hal;
diff --git a/system/gd/rust/hal/src/snoop.rs b/system/gd/rust/hal/src/snoop.rs
new file mode 100644
index 0000000..f5b7620
--- /dev/null
+++ b/system/gd/rust/hal/src/snoop.rs
@@ -0,0 +1,77 @@
+//! BT snoop logger
+
+use bt_common::sys_prop;
+use gddi::Stoppable;
+
+/// The different modes snoop logging can be in
+#[derive(Clone)]
+pub enum SnoopMode {
+ /// All logs disabled
+ Disabled,
+ /// Only sanitized logs
+ Filtered,
+ /// Log everything
+ Full,
+}
+
+/// There was an error parsing the mode from a string
+pub struct SnoopModeParseError;
+
+impl std::str::FromStr for SnoopMode {
+ type Err = SnoopModeParseError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "disabled" => Ok(SnoopMode::Disabled),
+ "filtered" => Ok(SnoopMode::Filtered),
+ "full" => Ok(SnoopMode::Full),
+ _ => Err(SnoopModeParseError),
+ }
+ }
+}
+
+/// All snoop logging config
+#[derive(Clone, Stoppable)]
+pub struct SnoopConfig {
+ path: String,
+ max_packets_per_file: u32,
+ mode: SnoopMode,
+}
+
+impl SnoopConfig {
+ /// Constructs a new snoop config
+ pub fn new() -> Self {
+ Self {
+ path: "/data/misc/bluetooth/logs/btsnoop_hci.log".to_string(),
+ max_packets_per_file: sys_prop::get_u32("persist.bluetooth.btsnoopsize")
+ .unwrap_or(0xFFFF),
+ mode: get_configured_snoop_mode()
+ .parse()
+ .unwrap_or(SnoopMode::Disabled),
+ }
+ }
+
+ /// Overwrites the laoded log path with the provided one
+ pub fn set_path(&mut self, value: String) {
+ self.path = value;
+ }
+
+ /// Overwrites the loaded mode with the provided one
+ pub fn set_mode(&mut self, value: SnoopMode) {
+ self.mode = value;
+ }
+}
+
+impl Default for SnoopConfig {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+fn get_configured_snoop_mode() -> String {
+ sys_prop::get("persist.bluetooth.btsnooplogmode").unwrap_or(if sys_prop::get_debuggable() {
+ sys_prop::get("persist.bluetooth.btsnoopdefaultmode").unwrap_or_default()
+ } else {
+ String::default()
+ })
+}
diff --git a/system/gd/rust/main/src/lib.rs b/system/gd/rust/main/src/lib.rs
index e294f86..5013a03 100644
--- a/system/gd/rust/main/src/lib.rs
+++ b/system/gd/rust/main/src/lib.rs
@@ -2,6 +2,7 @@
use gddi::{module, Registry, RegistryBuilder, Stoppable};
use bt_hal::rootcanal_hal::RootcanalConfig;
+use bt_hal::snoop::{SnoopConfig, SnoopMode};
use std::sync::Arc;
use tokio::runtime::Runtime;
use bt_common::GrpcFacade;
@@ -37,6 +38,16 @@
}
}
+ /// Configures snoop. If the path is provided, full logging is turned on
+ pub async fn configure_snoop(&self, path: Option<String>) {
+ let mut config = SnoopConfig::default();
+ if let Some(path) = path {
+ config.set_path(path);
+ config.set_mode(SnoopMode::Full);
+ }
+ self.registry.inject(config).await;
+ }
+
/// Helper forwarding to underlying registry
pub async fn get<T: 'static + Clone + Send + Sync + Stoppable>(&self) -> T {
self.registry.get::<T>().await