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

Commit 97cf0a34 authored by Hansong Zhang's avatar Hansong Zhang Committed by Automerger Merge Worker
Browse files

Initial commit for rusty BluetoothManager am: 1e064c7c

Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1662963

Change-Id: I528838ef9f1b5f4e7f35b2cce66128c242c87951
parents beefdb06 1e064c7c
Loading
Loading
Loading
Loading
+17 −19
Original line number Diff line number Diff line
#
#  Copyright 2021 Google, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at:
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

[package]
name = "btmgmt"
name = "manager_service"
version = "0.0.1"
edition = "2018"

[[bin]]
name = "btmgmtd"
path = "src/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

# bt deps
bt_common = { path = "../../common" }

# external deps
dbus = "0.9.2"
dbus-tokio = "0.7.3"
dbus-crossroads = "0.3.0"
inotify = "*"
nix = "*"
tokio = { version = "1.0", features = ["fs", "macros", "rt-multi-thread", "sync"] }

[[bin]]
name = "btmanagerd"
+148 −0
Original line number Diff line number Diff line
mod state_machine;

use dbus::channel::MatchingReceiver;
use dbus::message::MatchRule;
use dbus_crossroads::Crossroads;
use dbus_tokio::connection;

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = state_machine::start_new_state_machine_context();
    let proxy = context.get_proxy();

    // Connect to the D-Bus system bus (this is blocking, unfortunately).
    let (resource, c) = connection::new_system_sync()?;

    // The resource is a task that should be spawned onto a tokio compatible
    // reactor ASAP. If the resource ever finishes, you lost connection to D-Bus.
    tokio::spawn(async {
        let err = resource.await;
        panic!("Lost connection to D-Bus: {}", err);
    });

    // Let's request a name on the bus, so that clients can find us.
    c.request_name("org.chromium.bluetooth.Manager", false, true, false).await?;

    // Create a new crossroads instance.
    // The instance is configured so that introspection and properties interfaces
    // are added by default on object path additions.
    let mut cr = Crossroads::new();

    // Enable async support for the crossroads instance.
    cr.set_async_support(Some((
        c.clone(),
        Box::new(|x| {
            tokio::spawn(x);
        }),
    )));

    let iface_token = cr.register("org.chromium.bluetooth.Manager", |b| {
        b.method_with_cr_async(
            "Start",
            ("hci_interface",),
            (),
            |mut ctx, cr, (hci_interface,): (i32,)| {
                let proxy =
                    cr.data_mut::<state_machine::StateMachineProxy>(ctx.path()).unwrap().clone();
                println!("Incoming Start call for hci {}!", hci_interface);
                async move {
                    let result = proxy.start_bluetooth(hci_interface).await;
                    match result {
                        Ok(()) => ctx.reply(Ok(())),
                        Err(_) => ctx.reply(Err(dbus_crossroads::MethodErr::failed(
                            "cannot start Bluetooth",
                        ))),
                    }
                }
            },
        );
        b.method_with_cr_async("Stop", ("hci_interface",), (), |mut ctx, cr, (hci_interface,) : (i32,)| {
            let proxy =
                cr.data_mut::<state_machine::StateMachineProxy>(ctx.path()).unwrap().clone();
            println!("Incoming Stop call!");
            async move {
                let result = proxy.stop_bluetooth(hci_interface).await;
                match result {
                    Ok(()) => ctx.reply(Ok(())),
                    Err(_) => {
                        ctx.reply(Err(dbus_crossroads::MethodErr::failed("cannot stop Bluetooth")))
                    }
                }
            }
        });
        b.method_with_cr_async("GetState", (), ("result",), |mut ctx, cr, ()| {
            let proxy =
                cr.data_mut::<state_machine::StateMachineProxy>(ctx.path()).unwrap().clone();
            async move {
                let state = proxy.get_state().await;
                let result = match state {
                    state_machine::State::Off => 0,
                    state_machine::State::TurningOn => 1,
                    state_machine::State::On => 2,
                    state_machine::State::TurningOff => 3,
                };
                ctx.reply(Ok((result,)))
            }
        });
        b.method_with_cr_async(
            "RegisterStateChangeObserver",
            ("object_path",),
            (),
            |mut ctx, cr, (object_path,): (String,)| {
                let proxy =
                    cr.data_mut::<state_machine::StateMachineProxy>(ctx.path()).unwrap().clone();
                async move {
                    let result = proxy.register_state_change_observer(object_path.clone()).await;
                    match result {
                        Ok(()) => ctx.reply(Ok(())),
                        Err(_) => ctx.reply(Err(dbus_crossroads::MethodErr::failed(&format!(
                            "cannot register {}",
                            object_path
                        )))),
                    }
                }
            },
        );
        b.method_with_cr_async(
            "UnregisterStateChangeObserver",
            ("object_path",),
            (),
            |mut ctx, cr, (object_path,): (String,)| {
                let proxy =
                    cr.data_mut::<state_machine::StateMachineProxy>(ctx.path()).unwrap().clone();
                async move {
                    let result = proxy.unregister_state_change_observer(object_path.clone()).await;
                    match result {
                        Ok(()) => ctx.reply(Ok(())),
                        Err(_) => ctx.reply(Err(dbus_crossroads::MethodErr::failed(&format!(
                            "cannot unregister {}",
                            object_path
                        )))),
                    }
                }
            },
        );
    });

    // Let's add the "/org/chromium/bluetooth/Manager" path, which implements the org.chromium.bluetooth.Manager interface,
    // to the crossroads instance.
    cr.insert("/org/chromium/bluetooth/Manager", &[iface_token], proxy);

    // We add the Crossroads instance to the connection so that incoming method calls will be handled.
    c.start_receive(
        MatchRule::new_method_call(),
        Box::new(move |msg, conn| {
            cr.handle_message(msg, conn).unwrap();
            true
        }),
    );

    tokio::spawn(async move {
        state_machine::mainloop(context).await;
    });

    loop {}

    // Run forever.
    unreachable!()
}
+572 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −3
Original line number Diff line number Diff line
fn main() {
    println!("Bluetooth Management Daemon");
}