Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e98b3d2 authored by Zhengping Jiang's avatar Zhengping Jiang Committed by Automerger Merge Worker
Browse files

Floss: Notify kernel suspend ready and suspend done am: 0d1f32af

parents a4a7eb9f 0d1f32af
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ fn main() -> Result<(), Box<dyn Error>> {
    ))));
    let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(
        adapter_index,
        hci_index,
        tx.clone(),
        sig_notifier.clone(),
        intf.clone(),
+7 −0
Original line number Diff line number Diff line
@@ -462,6 +462,7 @@ pub struct Bluetooth {
    intf: Arc<Mutex<BluetoothInterface>>,

    adapter_index: i32,
    hci_index: i32,
    bonded_devices: HashMap<String, BluetoothDeviceContext>,
    ble_scanner_id: Option<u8>,
    ble_scanner_uuid: Option<Uuid128Bit>,
@@ -497,6 +498,7 @@ impl Bluetooth {
    /// Constructs the IBluetooth implementation.
    pub fn new(
        adapter_index: i32,
        hci_index: i32,
        tx: Sender<Message>,
        sig_notifier: Arc<(Mutex<bool>, Condvar)>,
        intf: Arc<Mutex<BluetoothInterface>>,
@@ -506,6 +508,7 @@ impl Bluetooth {
    ) -> Bluetooth {
        Bluetooth {
            adapter_index,
            hci_index,
            bonded_devices: HashMap::new(),
            callbacks: Callbacks::new(tx.clone(), Message::AdapterCallbackDisconnected),
            connection_callbacks: Callbacks::new(
@@ -602,6 +605,10 @@ impl Bluetooth {
        }
    }

    pub(crate) fn get_hci_index(&self) -> u16 {
        self.hci_index as u16
    }

    pub fn toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid128Bit>) {
        for profile in UuidHelper::get_supported_profiles().clone() {
            // Only toggle initializable profiles.
+49 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@ use num_derive::{FromPrimitive, ToPrimitive};
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc::Sender;

use bt_utils::socket::{BtSocket, HciChannels, MgmtCommand, HCI_DEV_NONE};

/// Defines the Suspend/Resume API.
///
/// This API is exposed by `btadapterd` and independent of the suspend/resume detection mechanism
@@ -63,6 +65,44 @@ const MASKED_EVENTS_FOR_SUSPEND: u64 = (1u64 << 4) | (1u64 << 19);
/// However, we will need to delay a few seconds to avoid co-ex issues with Wi-Fi reconnection.
const RECONNECT_AUDIO_ON_RESUME_DELAY_MS: u64 = 3000;

/// Default address for a virtual uhid device.
const BD_ADDR_DEFAULT: &str = "00:00:00:00:00:00";

/// TODO(b/286268874) Remove after the synchronization issue is resolved.
/// Delay sending suspend ready signal by some time.
const LE_RAND_CB_SUSPEND_READY_DELAY_MS: u64 = 100;

fn notify_suspend_state(hci_index: u16, suspended: bool) {
    log::debug!("Notify kernel suspend status: {} for hci{}", suspended, hci_index);
    let mut btsock = BtSocket::new();
    match btsock.open() {
        -1 => {
            panic!(
                "Bluetooth socket unavailable (errno {}). Try loading the kernel module first.",
                std::io::Error::last_os_error().raw_os_error().unwrap_or(0)
            );
        }
        x => log::debug!("notify suspend 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)
            );
        }
        _ => (),
    };

    let command = MgmtCommand::FlossNotifySuspendState(hci_index, suspended);
    let bytes_written = btsock.write_mgmt_packet(command.into());
    if bytes_written <= 0 {
        log::error!("Failed to notify suspend state on hci:{} to {}", hci_index, suspended);
    }
}

#[derive(FromPrimitive, ToPrimitive)]
#[repr(u32)]
pub enum SuspendType {
@@ -150,6 +190,8 @@ impl Suspend {
    }

    pub(crate) fn suspend_ready(&mut self, suspend_id: i32) {
        let hci_index = self.bt.lock().unwrap().get_hci_index();
        notify_suspend_state(hci_index, true);
        self.callbacks.for_all_callbacks(|callback| {
            callback.on_suspend_ready(suspend_id);
        });
@@ -254,6 +296,9 @@ impl ISuspend for Suspend {
    }

    fn resume(&mut self) -> bool {
        let hci_index = self.bt.lock().unwrap().get_hci_index();
        notify_suspend_state(hci_index, false);

        self.intf.lock().unwrap().set_default_event_mask_except(0u64, 0u64);

        // Restore event filter and accept list to normal.
@@ -345,6 +390,10 @@ impl BtifBluetoothCallbacks for Suspend {
            self.suspend_state.lock().unwrap().suspend_expected = false;
            let tx = self.tx.clone();
            tokio::spawn(async move {
                tokio::time::sleep(tokio::time::Duration::from_millis(
                    LE_RAND_CB_SUSPEND_READY_DELAY_MS,
                ))
                .await;
                let _result = tx.send(Message::SuspendReady(suspend_id)).await;
            });
        }
+32 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ impl MgmtPacket {
#[derive(FromPrimitive, ToPrimitive)]
pub enum MgmtCommandOpcode {
    ReadIndexList = 0x3,
    FlossNotifySuspendState = 0x103,
}

impl From<MgmtCommandOpcode> for u16 {
@@ -97,6 +98,7 @@ impl TryFrom<u16> for MgmtCommandOpcode {

pub enum MgmtCommand {
    ReadIndexList,
    FlossNotifySuspendState(u16, bool),
}

impl From<MgmtCommand> for MgmtPacket {
@@ -108,6 +110,12 @@ impl From<MgmtCommand> for MgmtPacket {
                len: 0,
                data: Vec::new(),
            },
            MgmtCommand::FlossNotifySuspendState(hci_index, suspended) => MgmtPacket {
                opcode: MgmtCommandOpcode::FlossNotifySuspendState.into(),
                index: HCI_DEV_NONE,
                len: MGMT_NOTIFY_SUSPEND_STATE_SIZE,
                data: MgmtCpNotifySuspendState::new(hci_index, u8::from(suspended)).to_data(),
            },
        }
    }
}
@@ -151,6 +159,27 @@ pub enum MgmtEvent {
    IndexRemoved(u16),
}

#[derive(Debug)]
pub struct MgmtCpNotifySuspendState {
    hci_id: u16,
    suspended: u8,
}

pub const MGMT_NOTIFY_SUSPEND_STATE_SIZE: u16 = 0x3;

impl MgmtCpNotifySuspendState {
    pub fn new(hci_id: u16, suspended: u8) -> Self {
        MgmtCpNotifySuspendState { hci_id, suspended }
    }

    pub fn to_data(&self) -> Vec<u8> {
        let mut v: Vec<u8> = Vec::new();
        v.extend_from_slice(self.hci_id.to_le_bytes().as_slice());
        v.extend_from_slice(self.suspended.to_le_bytes().as_slice());
        v
    }
}

impl TryFrom<MgmtPacket> for MgmtEvent {
    type Error = ();

@@ -200,6 +229,9 @@ impl TryFrom<MgmtPacket> for MgmtEvent {

                                MgmtCommandResponse::ReadIndexList { num_intf: len, interfaces }
                            }
                            MgmtCommandOpcode::FlossNotifySuspendState => {
                                MgmtCommandResponse::DataUnused
                            }
                        }
                    } else {
                        MgmtCommandResponse::DataUnused