Skip to content

Commit 01fd366

Browse files
authored
V2 management over specified MAC as BSID. (#9)
* V2 control specific lighthouse by BSID.
1 parent 6b71235 commit 01fd366

File tree

2 files changed

+49
-32
lines changed

2 files changed

+49
-32
lines changed

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,20 @@ Virtual reality basestation power management in Rust
1616
Usage: lighthouse [OPTIONS] --state <STATE>
1717
1818
Options:
19-
-s, --state <STATE> V1: [OFF|ON] [BSID] | V2: [OFF|ON|STANDBY]
20-
-b, --bsid <BSID> V1: Basestation BSID
21-
-v, --verbose... More output per occurrence
22-
-q, --quiet... Less output per occurrence
23-
-h, --help Print help information
19+
-s, --state <STATE> V1: [OFF|ON] [BSID] | V2: [OFF|ON|STANDBY] (BSID)
20+
-b, --bsid <BSID> Basestation BSID
21+
-v, --verbose... More output per occurrence
22+
-q, --quiet... Less output per occurrence
23+
-h, --help Print help information
24+
-t, --timeout <SECONDS> Scan timeout
2425
```
25-
V1 Basestations require an 8 character BSID found on the device.
26+
V1 Basestations require an 8 character BSID found on the device to work.
27+
28+
V2 Basestations do not require BSID. But you can specify their MAC address as BSID to manage a specific device.
2629

2730
## Example
2831
V1: `$ lighthouse -s on -b aabbccdd`
29-
V2: `$ lighthouse -s on`
32+
V2: `$ lighthouse -s on` or `$ lighthouse -s on -b A1:B2:C3:D4:E5:F6`
3033

3134
## macOS
3235
Enable the Bluetooth permission for your terminal. You can do the latter by going to System Preferences → Security & Privacy → Privacy → Bluetooth, clicking the '+' button, and selecting 'Terminal' (or iTerm or whichever terminal application you use).

src/main.rs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use clap::Parser;
88
use clap_verbosity_flag::Verbosity;
99
use lighthouse::Error;
1010
use tokio::time;
11-
use tracing::info;
11+
use tracing::{info};
1212
use tracing_log::AsTrace;
1313
use uuid::Uuid;
1414

@@ -17,7 +17,7 @@ const V2_UUID: &str = "00001525-1212-efde-1523-785feabcd124";
1717

1818
#[derive(Debug, Parser)]
1919
struct Args {
20-
/// V1: [OFF|ON] [BSID] | V2: [OFF|ON|STANDBY]
20+
/// V1: [OFF|ON] [BSID] | V2: [OFF|ON|STANDBY] (BSID)
2121
#[arg(short, long)]
2222
state: String,
2323

@@ -27,6 +27,9 @@ struct Args {
2727

2828
#[clap(flatten)]
2929
verbose: Verbosity,
30+
31+
#[arg(short, long, default_value_t = 10)]
32+
timeout: u64
3033
}
3134

3235
#[tokio::main(flavor = "current_thread")]
@@ -52,7 +55,8 @@ async fn main() -> Result<(), Error> {
5255
.await
5356
.map_err(Error::Btle)
5457
.expect("Can't scan BLE adapter for connected devices...");
55-
time::sleep(Duration::from_secs(10)).await;
58+
59+
time::sleep(Duration::from_secs(args.timeout)).await;
5660

5761
let peripherals = adapter.peripherals().await.map_err(Error::Btle)?;
5862
if peripherals.is_empty() {
@@ -71,7 +75,34 @@ async fn main() -> Result<(), Error> {
7175
};
7276

7377
let state = args.state.to_uppercase();
74-
if let Some(bsid) = &args.bsid {
78+
79+
info!("Found '{}' [{}]", name, peripheral.id());
80+
81+
if name.starts_with("LHB-") // v2
82+
{
83+
if let Some(bsid) = &args.bsid
84+
{
85+
if !peripheral.id().to_string().eq_ignore_ascii_case(bsid) {
86+
continue;
87+
}
88+
}
89+
90+
let cmd = match state.as_str() {
91+
"OFF" => vec![0x00],
92+
"ON" => vec![0x01],
93+
"STANDBY" => vec![0x02],
94+
_ => {
95+
return Err(Error::Message(
96+
"V2: Unknown State {state}, Available: [OFF|ON|STANDBY]",
97+
))
98+
}
99+
};
100+
101+
let uuid = Uuid::parse_str(V2_UUID).map_err(Error::Uuid)?;
102+
103+
lighthouse::write(adapter, peripheral.id(), &cmd, uuid).await?;
104+
}
105+
else if let Some(bsid) = &args.bsid { // v1
75106
if !name.starts_with("HTC BS")
76107
|| name[(name.len() - 4)..] != bsid[(bsid.len() - 4)..]
77108
{
@@ -84,7 +115,7 @@ async fn main() -> Result<(), Error> {
84115
let dd = u8::from_str_radix(&bsid[6..8], 16).map_err(Error::Std)?;
85116

86117
let cmd = match state.as_str() {
87-
"OFF" => vec![
118+
"OFF" | "STANDBY" => vec![
88119
0x12, 0x02, 0x00, 0x01, dd, cc, bb, aa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89120
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90121
],
@@ -102,26 +133,9 @@ async fn main() -> Result<(), Error> {
102133
let uuid = Uuid::parse_str(V1_UUID).map_err(Error::Uuid)?;
103134

104135
lighthouse::write(adapter, peripheral.id(), &cmd, uuid).await?;
105-
} else {
106-
if !name.starts_with("LHB-") {
107-
continue;
108-
}
109-
110-
let cmd = match state.as_str() {
111-
"OFF" => vec![0x00],
112-
"ON" => vec![0x01],
113-
"STANDBY" => vec![0x02],
114-
_ => {
115-
return Err(Error::Message(
116-
"V2: Unknown State {state}, Available: [OFF|ON|STANDBY]",
117-
))
118-
}
119-
};
120-
121-
let uuid = Uuid::parse_str(V2_UUID).map_err(Error::Uuid)?;
122-
123-
lighthouse::write(adapter, peripheral.id(), &cmd, uuid).await?;
124-
};
136+
}
137+
else { continue; } // not supported
138+
info!("{} [{}]: {}", name, peripheral.id(), state);
125139
}
126140
}
127141
Ok(())

0 commit comments

Comments
 (0)