Skip to content

Commit c92741a

Browse files
committed
bluetooth: rework HSP task, remove connect_task
Because we now have profile still registered, move the HSP task to init(). Remove connect_task and run its contents as a part of main function flow. The above steps allows to remove complex tasks aborting.
1 parent 99d101b commit c92741a

File tree

1 file changed

+31
-92
lines changed

1 file changed

+31
-92
lines changed

src/bluetooth.rs

Lines changed: 31 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub struct Bluetooth {
5959
adapter: Adapter,
6060
handle_aa: ProfileHandle,
6161
handle_hsp: Option<ProfileHandle>,
62-
task_hsp: Option<JoinHandle<Result<ProfileHandle>>>,
62+
task_hsp: Option<JoinHandle<()>>,
6363
handle_agent: AgentHandle,
6464
btle_handle: Option<bluer::gatt::local::ApplicationHandle>,
6565
adv_handle: Option<bluer::adv::AdvertisementHandle>,
@@ -117,6 +117,7 @@ pub async fn init(
117117
info!("{} 📱 AA Wireless Profile: registered", NAME);
118118

119119
let mut handle_hsp = None;
120+
let mut task_hsp = None;
120121
if !dongle_mode {
121122
// Headset profile
122123
let profile = Profile {
@@ -127,9 +128,21 @@ pub async fn init(
127128
..Default::default()
128129
};
129130
match session.register_profile(profile).await {
130-
Ok(handle) => {
131+
Ok(mut handle) => {
131132
info!("{} 🎧 Headset Profile (HSP): registered", NAME);
132-
handle_hsp = Some(handle);
133+
// handling connection to headset profile in own task
134+
// it only accepts each incoming connection
135+
task_hsp = Some(tokio::spawn(async move {
136+
loop {
137+
let req = handle.next().await.expect("received no connect request");
138+
info!(
139+
"{} 🎧 Headset Profile (HSP): connect from: <b>{}</>",
140+
NAME,
141+
req.device()
142+
);
143+
let _ = req.accept();
144+
}
145+
}));
133146
}
134147
Err(e) => {
135148
warn!(
@@ -145,7 +158,7 @@ pub async fn init(
145158
adapter,
146159
handle_aa,
147160
handle_hsp,
148-
task_hsp: None,
161+
task_hsp,
149162
handle_agent,
150163
btle_handle: None,
151164
adv_handle: None,
@@ -285,26 +298,21 @@ impl Bluetooth {
285298
info!("{} ⏳ Waiting for phone to connect via bluetooth...", NAME);
286299

287300
// try to connect to saved devices or provided one via command line
288-
let mut connect_task: Option<JoinHandle<Result<()>>> = None;
289301
if let Some(addresses_to_connect) = connect.0 {
290302
if !stopped {
291303
let adapter_cloned = self.adapter.clone();
292304

293-
connect_task = Some(tokio::spawn(async move {
294-
let addresses: Vec<Address> = if addresses_to_connect
295-
.iter()
296-
.any(|addr| *addr == Address::any())
297-
{
298-
info!("{} 🥏 Enumerating known bluetooth devices...", NAME);
299-
adapter_cloned.device_addresses().await?
300-
} else {
301-
addresses_to_connect
302-
};
303-
// exit if we don't have anything to connect to
304-
if addresses.is_empty() {
305-
return Ok(());
306-
}
307-
305+
let addresses: Vec<Address> = if addresses_to_connect
306+
.iter()
307+
.any(|addr| *addr == Address::any())
308+
{
309+
info!("{} 🥏 Enumerating known bluetooth devices...", NAME);
310+
adapter_cloned.device_addresses().await?
311+
} else {
312+
addresses_to_connect
313+
};
314+
// exit if we don't have anything to connect to
315+
if !addresses.is_empty() {
308316
info!("{} 🧲 Attempting to start an AndroidAuto session via bluetooth with the following devices, in this order: {:?}", NAME, addresses);
309317
let try_connect_bluetooth_addresses_retry = || {
310318
Bluetooth::try_connect_bluetooth_addresses(
@@ -332,69 +340,19 @@ impl Bluetooth {
332340
},
333341
)
334342
.await?;
335-
return Ok(());
336-
}));
337-
}
338-
}
339-
340-
// handling connection to headset profile in own task
341-
let mut task_hsp = {
342-
if let Some(mut handle_hsp) = self.handle_hsp.take() {
343-
Some(tokio::spawn(async move {
344-
let req = handle_hsp
345-
.next()
346-
.await
347-
.expect("received no connect request");
348-
info!(
349-
"{} 🎧 Headset Profile (HSP): connect from: <b>{}</>",
350-
NAME,
351-
req.device()
352-
);
353-
req.accept()?;
354-
355-
Ok(handle_hsp)
356-
}))
357-
} else {
358-
None
359-
}
360-
};
361-
362-
/// we might have a tasks which should be aborted on errors
363-
/// this function is taking care of this before next bluetooth
364-
/// connection attempts
365-
fn abort_tasks(
366-
t1: &mut Option<JoinHandle<Result<()>>>,
367-
t2: &mut Option<JoinHandle<Result<ProfileHandle>>>,
368-
) {
369-
if let Some(task) = t1 {
370-
task.abort();
371-
}
372-
if let Some(task) = t2 {
373-
task.abort();
343+
}
374344
}
375345
}
376346

377347
let req = timeout(bt_timeout, self.handle_aa.next())
378-
.await
379-
.map_err(|e| {
380-
abort_tasks(&mut connect_task, &mut task_hsp);
381-
e
382-
})?
348+
.await?
383349
.expect("received no connect request");
384350
info!(
385351
"{} 📱 AA Wireless Profile: connect from: <b>{}</>",
386352
NAME,
387353
req.device()
388354
);
389-
let stream = req.accept().map_err(|e| {
390-
abort_tasks(&mut connect_task, &mut task_hsp);
391-
e
392-
})?;
393-
394-
// we have a connection from phone, stop connect_task
395-
if let Some(task) = connect_task {
396-
task.abort();
397-
}
355+
let stream = req.accept()?;
398356

399357
Ok(stream)
400358
}
@@ -583,25 +541,6 @@ impl Bluetooth {
583541
//drop(state.handle_agent);
584542
//info!("{} 📱 Removing AA profile", NAME);
585543
//drop(state.handle_aa);
586-
587-
// HSP profile is/was running in own task
588-
if let Some(handle) = self.task_hsp.take() {
589-
match timeout(Duration::from_secs_f32(2.5), handle).await {
590-
Ok(task_handle) => match task_handle? {
591-
Ok(handle_hsp) => {
592-
info!("{} 🎧 Removing HSP profile", NAME);
593-
drop(handle_hsp);
594-
}
595-
Err(e) => {
596-
warn!("{} 🎧 HSP profile error: {}", NAME, e);
597-
}
598-
},
599-
Err(e) => {
600-
warn!("{} 🎧 Error waiting for HSP profile task: {}", NAME, e);
601-
}
602-
}
603-
}
604-
605544
Ok(())
606545
}
607546

0 commit comments

Comments
 (0)