forked from auracaster/bumble_mirror
113 lines
3.1 KiB
Rust
113 lines
3.1 KiB
Rust
// Copyright 2023 Google LLC
|
|
//
|
|
// 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.
|
|
|
|
//! Counterpart to the Python example `battery_server.py`.
|
|
//!
|
|
//! Start an Android emulator from Android Studio, or otherwise have netsim running.
|
|
//!
|
|
//! Run the server from the project root:
|
|
//! ```
|
|
//! PYTHONPATH=. python examples/battery_server.py \
|
|
//! examples/device1.json android-netsim
|
|
//! ```
|
|
//!
|
|
//! Then run this example from the `rust` directory:
|
|
//!
|
|
//! ```
|
|
//! PYTHONPATH=..:/path/to/virtualenv/site-packages/ \
|
|
//! cargo run --example battery_client -- \
|
|
//! --transport android-netsim \
|
|
//! --target-addr F0:F1:F2:F3:F4:F5
|
|
//! ```
|
|
|
|
use bumble::wrapper::{
|
|
device::{Device, Peer},
|
|
profile::BatteryServiceProxy,
|
|
transport::Transport,
|
|
PyObjectExt,
|
|
};
|
|
use clap::Parser as _;
|
|
use log::info;
|
|
use owo_colors::OwoColorize;
|
|
use pyo3::prelude::*;
|
|
|
|
#[pyo3_asyncio::tokio::main]
|
|
async fn main() -> PyResult<()> {
|
|
env_logger::builder()
|
|
.filter_level(log::LevelFilter::Info)
|
|
.init();
|
|
|
|
let cli = Cli::parse();
|
|
|
|
let transport = Transport::open(cli.transport).await?;
|
|
|
|
let device = Device::with_hci(
|
|
"Bumble",
|
|
"F0:F1:F2:F3:F4:F5",
|
|
transport.source()?,
|
|
transport.sink()?,
|
|
)?;
|
|
|
|
device.power_on().await?;
|
|
|
|
let conn = device.connect(&cli.target_addr).await?;
|
|
let mut peer = Peer::new(conn)?;
|
|
for mut s in peer.discover_services().await? {
|
|
s.discover_characteristics().await?;
|
|
}
|
|
let battery_service = peer
|
|
.create_service_proxy::<BatteryServiceProxy>()?
|
|
.ok_or(anyhow::anyhow!("No battery service found"))?;
|
|
|
|
let mut battery_level_char = battery_service
|
|
.battery_level()?
|
|
.ok_or(anyhow::anyhow!("No battery level characteristic"))?;
|
|
info!(
|
|
"{} {}",
|
|
"Initial Battery Level:".green(),
|
|
battery_level_char
|
|
.read_value()
|
|
.await?
|
|
.extract_with_gil::<u32>()?
|
|
);
|
|
battery_level_char
|
|
.subscribe(|_py, args| {
|
|
info!(
|
|
"{} {:?}",
|
|
"Battery level update:".green(),
|
|
args.get_item(0)?.extract::<u32>()?,
|
|
);
|
|
Ok(())
|
|
})
|
|
.await?;
|
|
|
|
// wait until user kills the process
|
|
tokio::signal::ctrl_c().await?;
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(clap::Parser)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct Cli {
|
|
/// Bumble transport spec.
|
|
///
|
|
/// <https://google.github.io/bumble/transports/index.html>
|
|
#[arg(long)]
|
|
transport: String,
|
|
|
|
/// Address to connect to
|
|
#[arg(long)]
|
|
target_addr: String,
|
|
}
|