Skip to content
Snippets Groups Projects
Commit 656a9570 authored by Yun-hao Chung's avatar Yun-hao Chung Committed by Automerger Merge Worker
Browse files

Merge "Floss: Retry socket bind on EINVAL" into main am: 92a4c663 am: 2021b1f0

parents 2d30ce63 2021b1f0
No related branches found
No related tags found
No related merge requests found
......@@ -32,6 +32,7 @@ regex = "1.5"
serde_json = "1.0"
syslog = "6"
tokio = { version = "1.0", features = ["fs", "macros", "rt-multi-thread", "sync"] }
libc = "0.2"
[build-dependencies]
pkg-config = "0.3.19"
......
......@@ -5,6 +5,7 @@ use bt_utils::socket::{
BtSocket, HciChannels, MgmtCommand, MgmtCommandResponse, MgmtEvent, HCI_DEV_NONE,
};
use libc;
use log::{debug, error, info, warn};
use nix::sys::signal::{self, Signal};
use nix::unistd::Pid;
......@@ -36,6 +37,10 @@ pub const INDEX_REMOVED_DEBOUNCE_TIME: Duration = Duration::from_millis(150);
/// to avoid dead process + PID not cleaned up from happening.
pub const PID_RUNNING_CHECK_PERIOD: Duration = Duration::from_secs(60);
const HCI_BIND_MAX_RETRY: i32 = 2;
const HCI_BIND_RETRY_INTERVAL: Duration = Duration::from_millis(10);
#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(u32)]
pub enum ProcessState {
......@@ -362,19 +367,37 @@ fn configure_hci(hci_tx: mpsc::Sender<Message>) {
x => debug!("Socket open at fd: {}", x),
}
// Bind to control channel (which is used for mgmt commands). We provide
// HCI_DEV_NONE because we don't actually need a valid HCI dev for some MGMT commands.
match btsock.bind_channel(HciChannels::Control, HCI_DEV_NONE) {
-1 => {
panic!(
"Failed to bind control channel with errno={}",
std::io::Error::last_os_error().raw_os_error().unwrap_or(0)
);
tokio::spawn(async move {
// Bind to control channel (which is used for mgmt commands). We provide
// HCI_DEV_NONE because we don't actually need a valid HCI dev for some MGMT commands.
let mut bind_succ = false;
for _i in 0..HCI_BIND_MAX_RETRY {
match btsock.bind_channel(HciChannels::Control, HCI_DEV_NONE) {
-1 => {
match std::io::Error::last_os_error().raw_os_error().unwrap_or(0) {
libc::EINVAL => {
// If MGMT hasn't been initialized EINVAL will be returned.
// Just wait for a short time and try again.
debug!("Got EINVAL in bind. Wait and try again");
tokio::time::sleep(HCI_BIND_RETRY_INTERVAL).await;
continue;
}
others => {
panic!("Failed to bind control channel with errno={}", others);
}
}
}
_ => {
bind_succ = true;
break;
}
};
}
if !bind_succ {
panic!("bind failed too many times!!");
}
_ => (),
};
tokio::spawn(async move {
debug!("Spawned hci notify task");
// Make this into an AsyncFD and start using it for IO
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment