Skip to content

Commit

Permalink
Remove unnecessary comment
Browse files Browse the repository at this point in the history
  • Loading branch information
Meigs2 committed Feb 26, 2025
1 parent 4d11a11 commit e338a46
Showing 1 changed file with 178 additions and 17 deletions.
195 changes: 178 additions & 17 deletions examples/apps/src/ble_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,29 @@ use bt_hci::cmd::le::LeSetScanParams;
use bt_hci::controller::ControllerCmdSync;
use core::cell::RefCell;
use embassy_futures::join::join;
use embassy_futures::select::select;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::signal::Signal;
use embassy_time::{Duration, Timer};
use heapless::Deque;
use heapless::{Deque, String, Vec};
use trouble_host::prelude::*;

/// Max number of connections
const CONNECTIONS_MAX: usize = 1;
const L2CAP_CHANNELS_MAX: usize = 1;
const L2CAP_MTU: usize = 27;

pub async fn run<C>(controller: C)
const IDENTIFY: [u8; 20] = [
239, 221, 11, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 104, 59,
];

const NOTIFICATION_REQUEST: [u8; 14] = [
0xef, 0xdd, 0x0c, 0x09, 0x00, 0x01, 0x01, 0x02, 0x02, 0x05, 0x03, 0x04, 0x15, 0x06,
];
const HEARTBEAT: [u8; 7] = [239, 221, 0, 2, 0, 2, 0];

const HEARTBEAT_INTERVAL: Duration = Duration::from_millis(2000);

pub async fn run<C, const L2CAP_MTU: usize>(controller: C)
where
C: Controller + ControllerCmdSync<LeSetScanParams>,
{
Expand All @@ -23,38 +36,149 @@ where
let mut resources: HostResources<CONNECTIONS_MAX, L2CAP_CHANNELS_MAX, L2CAP_MTU> = HostResources::new();
let stack = trouble_host::new(controller, &mut resources).set_random_address(address);
let Host {
central, mut runner, ..
mut central,
mut runner,
..
} = stack.build();

let printer = Printer {
seen: RefCell::new(Deque::new()),
found: Signal::new(),
};
let mut scanner = Scanner::new(central);
let _ = join(runner.run_with_handler(&printer), async {
let mut config = ScanConfig::default();
config.active = true;
config.phys = PhySet::M1;
config.interval = Duration::from_secs(1);
config.window = Duration::from_secs(1);
let mut _session = scanner.scan(&config).await.unwrap();
// Scan forever
loop {
Timer::after(Duration::from_secs(1)).await;
}

let _ = select(runner.run_with_handler(&printer), async {
let mut central = {
let mut scanner = Scanner::new(central);
{
let mut config = ScanConfig::default();
config.active = true;
config.phys = PhySet::M1;
config.interval = Duration::from_secs(1);
config.window = Duration::from_secs(1);
let mut _session = scanner.scan(&config).await.unwrap();
// Scan until we've found an inner value
loop {
if !printer.found.signaled() {
Timer::after(Duration::from_secs(1)).await;
continue;
}

break;
}
}

scanner.into_inner()
};

let found = printer.found.try_take().unwrap();

let (addr, addr_kind) = found;
info!("Found the device! addr: {:?}, kind: {:?}", addr, addr_kind);

let config = ConnectConfig {
connect_params: Default::default(),
scan_config: ScanConfig {
filter_accept_list: &[(addr_kind, &addr)],
..Default::default()
},
};

let conn = central.connect(&config).await.unwrap();
info!("Connected, creating gatt client");

let client = GattClient::<C, 10, L2CAP_MTU>::new(&stack, &conn).await.unwrap();

let _ = join(client.task(), async {
info!("Looking for battery service");
let services = client.services_by_uuid(&Uuid::new_short(0x1820)).await.unwrap();
let service = services.first().unwrap().clone();

info!("Looking for value handle");
let c: Characteristic<u8> = client
.characteristic_by_uuid(&service, &Uuid::new_short(0x2a80))
.await
.unwrap();

info!("Characteristic: {:?}", c.handle);

info!("Subscribing notifications");
let mut listener = client.subscribe(&c, false).await.unwrap();

join(
async {
loop {
let data = listener.next().await;
info!("Got notification: {:?} (val: {})", data.as_ref(), data.as_ref()[0]);
}
},
async {
Timer::after(Duration::from_millis(150)).await;
info!("Writing Heartbeat");
client
.write_characteristic_without_response(&c, &IDENTIFY)
.await
.unwrap();
client
.write_characteristic_without_response(&c, &NOTIFICATION_REQUEST)
.await
.unwrap();
loop {
Timer::after(HEARTBEAT_INTERVAL).await;
info!("Writing Heartbeat");
client
.write_characteristic_without_response(&c, &IDENTIFY)
.await
.unwrap();
}
},
)
.await;

info!("Disconnected");
})
.await;
})
.await;

let Some(value) = printer.found.try_take() else {
panic!("Idk how you got here but you did. Good job.")
};
}

struct Printer {
seen: RefCell<Deque<BdAddr, 128>>,
found: Signal<CriticalSectionRawMutex, (BdAddr, AddrKind)>,
}

impl EventHandler for Printer {
fn on_adv_reports(&self, mut it: LeAdvReportsIter<'_>) {
let mut seen = self.seen.borrow_mut();
while let Some(Ok(report)) = it.next() {
if seen.iter().find(|b| b.raw() == report.addr.raw()).is_none() {
info!("discovered: {:?}", report.addr);
//info!("discovered: {:?}", report.addr);
let mut advertisements = AdStructure::decode(report.data);
while let Some(Ok(ad)) = advertisements.next() {
match ad {
AdStructure::CompleteLocalName(n) => {
let value = get_name_string(n);
info!("Complete Name: {:?}", value);
if value.starts_with("ACAIA") {
info!("SIGNALING");
self.found.signal((report.addr, report.addr_kind))
}
}
AdStructure::ShortenedLocalName(n) => {
let value = get_name_string(n);
info!("Short Name: {:?}", value);
if value.starts_with("ACAIA") {
info!("SIGNALING");
self.found.signal((report.addr, report.addr_kind))
}
}
_ => {}
}
}

if seen.is_full() {
seen.pop_front();
}
Expand All @@ -63,3 +187,40 @@ impl EventHandler for Printer {
}
}
}

fn get_name_string(slice: &[u8]) -> String<291> {
let mut vec = Vec::<u8, 291>::new();
vec.extend_from_slice(&slice).unwrap();
String::from_utf8(vec).unwrap()
}

fn encode<const N: usize>(msg_type: u8, payload: &[u8]) -> [u8; N] {
let header1 = 0xef; // Replace with your actual HEADER1 value
let header2 = 0xdd; // Replace with your actual HEADER2 value

let mut bytes = [0u8; N];

bytes[0] = header1;
bytes[1] = header2;
bytes[2] = msg_type;

let mut cksum1 = 0;
let mut cksum2 = 0;

for (i, &val) in payload.iter().enumerate() {
let val = val & 0xff;
bytes[3 + i] = val;
if i % 2 == 0 {
cksum1 += val as u16;
} else {
cksum2 += val as u16;
}
}

bytes[payload.len() + 3] = (cksum1 & 0xFF) as u8;
bytes[payload.len() + 4] = (cksum2 & 0xFF) as u8;

info!("{:?}", bytes);

bytes
}

0 comments on commit e338a46

Please sign in to comment.