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

Commit 64de3903 authored by Rahul Arya's avatar Rahul Arya
Browse files

[Connection Manager] Expose connection manager API from C++

This API is essentially the same as the old connection manager API. The
difference is that we handle address resolution + connection tracking within the
connection manager, rather than assuming all addresses are public.

Bug: 272572974
Test: compiles
Change-Id: I066a9a1fececa608186db3ea9253ea442b018a69
parent 6ca00da4
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ use self::le_manager::{
mod ffi;
pub mod le_manager;

pub use ffi::{LeAclManagerImpl, LeAclManagerShim};
pub use ffi::{register_callbacks, LeAclManagerImpl, LeAclManagerShim};

/// Possible errors returned when making a connection attempt
#[derive(Debug)]
@@ -146,14 +146,14 @@ impl ConnectionManager {
    }

    fn on_le_connect_success(&self, _conn: LeConnection) {
        todo!()
        // TODO(aryarahul)
    }

    fn on_le_connect_fail(&self, _address: AddressWithType, _status: ErrorCode) {
        todo!()
        // TODO(aryarahul)
    }

    fn on_disconnect(&self, _address: AddressWithType) {
        todo!()
        // TODO(aryarahul)
    }
}
+72 −2
Original line number Diff line number Diff line
@@ -4,16 +4,17 @@ use std::{fmt::Debug, pin::Pin};

use cxx::UniquePtr;
pub use inner::*;
use log::warn;
use tokio::{
    sync::mpsc::{unbounded_channel, UnboundedSender},
    task::spawn_local,
};

use crate::core::address::AddressWithType;
use crate::{core::address::AddressWithType, do_in_rust_thread};

use super::{
    le_manager::{ErrorCode, InactiveLeAclManager, LeAclManager, LeAclManagerConnectionCallbacks},
    LeConnection,
    ConnectionManagerClient, LeConnection,
};

unsafe impl Send for LeAclManagerShim {}
@@ -70,6 +71,21 @@ mod inner {
        #[cxx_name = "OnDisconnect"]
        fn on_disconnect(&self, address: AddressWithType);
    }

    #[namespace = "bluetooth::connection"]
    unsafe extern "C++" {
        include!("stack/arbiter/acl_arbiter.h");

        /// Register APIs exposed by Rust
        fn RegisterRustApis(
            start_direct_connection: fn(client_id: u8, address: AddressWithType),
            stop_direct_connection: fn(client_id: u8, address: AddressWithType),
            add_background_connection: fn(client_id: u8, address: AddressWithType),
            remove_background_connection: fn(client_id: u8, address: AddressWithType),
            remove_client: fn(client_id: u8),
            stop_all_connections_to_device: fn(address: AddressWithType),
        );
    }
}

impl LeAclManagerShim {
@@ -153,3 +169,57 @@ impl Debug for LeAclManagerImpl {
        f.debug_tuple("LeAclManagerImpl").finish()
    }
}

/// Registers all connection-manager callbacks into C++ dependencies
pub fn register_callbacks() {
    RegisterRustApis(
        |client, address| {
            let client = ConnectionManagerClient::GattClient(client);
            do_in_rust_thread(move |modules| {
                let result = modules.connection_manager.start_direct_connection(client, address);
                if let Err(err) = result {
                    warn!("Failed to start direct connection from {client:?} to {address:?} ({err:?})")
                }
            });
        },
        |client, address| {
            let client = ConnectionManagerClient::GattClient(client);
            do_in_rust_thread(move |modules| {
                let result = modules.connection_manager.cancel_direct_connection(client, address);
                if let Err(err) = result {
                    warn!("Failed to cancel direct connection from {client:?} to {address:?} ({err:?})")
                }
            })
        },
        |client, address| {
            let client = ConnectionManagerClient::GattClient(client);
            do_in_rust_thread(move |modules| {
                let result = modules.connection_manager.add_background_connection(client, address);
                if let Err(err) = result {
                    warn!("Failed to add background connection from {client:?} to {address:?} ({err:?})")
                }
            })
        },
        |client, address| {
            let client = ConnectionManagerClient::GattClient(client);
            do_in_rust_thread(move |modules| {
                let result =
                    modules.connection_manager.remove_background_connection(client, address);
                if let Err(err) = result {
                    warn!("Failed to remove background connection from {client:?} to {address:?} ({err:?})")
                }
            })
        },
        |client| {
            let client = ConnectionManagerClient::GattClient(client);
            do_in_rust_thread(move |modules| {
                modules.connection_manager.remove_client(client);
            })
        },
        |address| {
            do_in_rust_thread(move |modules| {
                modules.connection_manager.cancel_unconditionally(address);
            })
        },
    )
}
+33 −0
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@
#include "hci/address_with_type.h"
#include "hci/hci_packets.h"
#include "main/shim/entry.h"
#ifndef TARGET_FLOSS
#include "src/connection/ffi.rs.h"
#endif
#include "src/core/ffi/types.h"
#include "stack/btm/btm_dev.h"

namespace bluetooth {
@@ -118,5 +121,35 @@ void LeAclManagerShim::RegisterRustCallbacks(
}
#endif

namespace {

std::optional<RustConnectionManager> connection_manager;

}  // namespace

RustConnectionManager& GetConnectionManager() {
  return connection_manager.value();
}

void RegisterRustApis(
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        start_direct_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        stop_direct_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        add_background_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        remove_background_connection,
    ::rust::Fn<void(uint8_t client_id)> remove_client,
    ::rust::Fn<void(core::AddressWithType address)>
        stop_all_connections_to_device) {
  connection_manager = {start_direct_connection,
                        stop_direct_connection,
                        add_background_connection,
                        remove_background_connection,
                        remove_client,
                        stop_all_connections_to_device};
}

}  // namespace connection
}  // namespace bluetooth
+29 −0
Original line number Diff line number Diff line
@@ -45,5 +45,34 @@ class LeAclManagerShim {
  std::unique_ptr<impl> pimpl_;
};

void RegisterRustApis(
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        start_direct_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        stop_direct_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        add_background_connection,
    ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
        remove_background_connection,
    ::rust::Fn<void(uint8_t client_id)> remove_client,
    ::rust::Fn<void(core::AddressWithType address)>
        stop_all_connections_to_device);

struct RustConnectionManager {
  ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
      start_direct_connection;
  ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
      stop_direct_connection;
  ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
      add_background_connection;
  ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
      remove_background_connection;
  ::rust::Fn<void(uint8_t client_id)> remove_client;
  ::rust::Fn<void(core::AddressWithType address)>
      stop_all_connections_to_device;
};

RustConnectionManager& GetConnectionManager();

}  // namespace connection
}  // namespace bluetooth
+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ impl GlobalModuleRegistry {

        // First, setup FFI and C++ modules
        gatt::arbiter::initialize_arbiter();
        connection::register_callbacks();

        // Now enter the runtime
        local.block_on(&rt, async {
Loading