Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f22b0dc9 authored by howardchung's avatar howardchung
Browse files

Floss: implement restricted mode in btclient

Implement the following command options:
  --restricted		disallow toggling adapter power when set
  --command <COMMAND>	execute the command without entering the shell

Bug: 239432313
Test: deploy and run
1. btclient; (in shell) adapter disable
2. btclient --restricted; (in shell) adapter disable
3. btclient --command "adapter disable"
4. btclient --restricted --command "adapter disable"
Verified 1 and 3 success. 2 and 4 fail.
Tag: #floss

Change-Id: Ied236ce3f336ae89847de28b000e21ccd58eeb0b
parent 04f609bd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ futures = "0.3.13"
num-traits = "*"
tokio = { version = "1", features = ['bytes', 'fs', 'io-util', 'libc', 'macros', 'memchr', 'mio', 'net', 'num_cpus', 'rt', 'rt-multi-thread', 'sync', 'time', 'tokio-macros'] }

clap = "2.33.3"
[build-dependencies]
pkg-config = "0.3.19"

+8 −0
Original line number Diff line number Diff line
@@ -306,9 +306,17 @@ impl CommandHandler {
            "adapter <enable|disable|show|discoverable|connectable|set-name>",
            || match &args[0][0..] {
                "enable" => {
                    if self.context.lock().unwrap().is_restricted {
                        println!("You are not allowed to toggle adapter power");
                        return;
                    }
                    self.context.lock().unwrap().manager_dbus.start(default_adapter);
                }
                "disable" => {
                    if self.context.lock().unwrap().is_restricted {
                        println!("You are not allowed to toggle adapter power");
                        return;
                    }
                    self.context.lock().unwrap().manager_dbus.stop(default_adapter);
                }
                "show" => {
+33 −10
Original line number Diff line number Diff line
#[macro_use]
extern crate clap;
use clap::{App, Arg};

use std::collections::{HashMap, HashSet};
use std::sync::{Arc, Mutex};

@@ -112,6 +116,9 @@ pub(crate) struct ClientContext {

    /// Identifies the callback to receive IBluetoothSocketManagerCallback method calls.
    socket_manager_callback_id: Option<u32>,

    /// Is btclient running in restricted mode?
    is_restricted: bool,
}

impl ClientContext {
@@ -119,6 +126,7 @@ impl ClientContext {
        dbus_connection: Arc<SyncConnection>,
        dbus_crossroads: Arc<Mutex<Crossroads>>,
        tx: mpsc::Sender<ForegroundActions>,
        is_restricted: bool,
    ) -> ClientContext {
        // Manager interface is almost always available but adapter interface
        // requires that the specific adapter is enabled.
@@ -151,6 +159,7 @@ impl ClientContext {
            active_scanner_ids: HashSet::new(),
            adv_sets: HashMap::new(),
            socket_manager_callback_id: None,
            is_restricted,
        }
    }

@@ -262,7 +271,12 @@ enum ForegroundActions {

/// Runs a command line program that interacts with a Bluetooth stack.
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // TODO: Process command line arguments.
    let matches = App::new("btclient")
        .arg(Arg::with_name("restricted").long("restricted").takes_value(false))
        .arg(Arg::with_name("command").short("c").long("command").takes_value(true))
        .get_matches();
    let command = value_t!(matches, "command", String);
    let is_restricted = matches.is_present("restricted");

    topstack::get_runtime().block_on(async move {
        // Connect to D-Bus system bus.
@@ -296,8 +310,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
        let (tx, rx) = mpsc::channel::<ForegroundActions>(10);

        // Create the context needed for handling commands
        let context =
            Arc::new(Mutex::new(ClientContext::new(conn.clone(), cr.clone(), tx.clone())));
        let context = Arc::new(Mutex::new(ClientContext::new(
            conn.clone(),
            cr.clone(),
            tx.clone(),
            is_restricted,
        )));

        // Check if manager interface is valid. We only print some help text before failing on the
        // first actual access to the interface (so we can also capture the actual reason the
@@ -337,14 +355,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

        let mut handler = CommandHandler::new(context.clone());

        let args: Vec<String> = std::env::args().collect();

        // Allow command line arguments to be read
        if args.len() > 1 {
            handler.process_cmd_line(&args[1], &args[2..].to_vec());
        } else {
        match command {
            Ok(command) => {
                let mut iter = command.split(' ').map(String::from);
                handler.process_cmd_line(
                    &iter.next().unwrap_or(String::from("")),
                    &iter.collect::<Vec<String>>(),
                );
            }
            _ => {
                start_interactive_shell(handler, tx, rx, context).await;
            }
        };
        return Result::Ok(());
    })
}