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

Commit 0dcaae6a authored by David Duarte's avatar David Duarte
Browse files

RootCanal: Implement LMP as a rust library

The implementation is switched from a custom
Link Layer Protocol to LMP to be more close to
the specification.

This is implemented under a feature flag because
currently we are unable to use Rust inside the emulator
so we keep the old implementation for the emulator
until we find a better solution.

This is implemented in Rust to have access to
coroutines (via async/await) to ease the implementation.

Bug: 216620310
Bug: 209804169
Bug: 209803517
Test: Run AVDTP/SNK PTS-bot tests on Eiffel
Change-Id: Ib2795ea31fe3658e4dafb0cf9ea41f473291b8c0
parent 11b13834
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -574,6 +574,7 @@ rust_library {
    crate_name: "bt_packets",
    srcs: ["rust/packets/lib.rs", ":BluetoothGeneratedPackets_rust"],
    edition: "2018",
    vendor_available : true,
    host_supported: true,
    proc_macros: ["libnum_derive"],
    rustlibs: [
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ cc_defaults {
        "-Wextra",
        "-Werror",
        "-fvisibility=hidden",
        "-DROOTCANAL_LMP",
    ],
    local_include_dirs: [
        "include",
@@ -95,6 +96,9 @@ cc_library_static {
    shared_libs: [
        "liblog",
    ],
    whole_static_libs: [
        "liblmp",
    ],
    static_libs: [
        "libjsoncpp",
        "libscriptedbeaconpayload-protos-lite",
+43 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "system_bt_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["system_bt_license"],
}

rust_ffi {
    name: "liblmp",
    host_supported: true,
    vendor_available : true,
    crate_name: "lmp",
    srcs: [
        "src/lib.rs",
        ":LmpGeneratedPackets_rust",
    ],
    edition: "2018",
    proc_macros: ["libnum_derive"],
    rustlibs: [
        "libbt_packets",
        "libbytes",
        "libnum_traits",
        "libthiserror",
        "libpin_utils",
    ],
    include_dirs: ["include"],
}

genrule {
    name: "LmpGeneratedPackets_rust",
    tools: [
        "bluetooth_packetgen",
    ],
    cmd: "$(location bluetooth_packetgen) --include=packages/modules/Bluetooth/tools/rootcanal/lmp  --out=$(genDir) $(in) --rust",
    srcs: [
        "lmp_packets.pdl",
    ],
    out: [
        "lmp_packets.rs",
    ],
}
+11 −0
Original line number Diff line number Diff line
# For documentation, see: https://github.com/eqrion/cbindgen/blob/master/docs.md

language = "C++"
pragma_once = true
autogen_warning = '''
// This file is autogenerated by:
//   cbindgen --config cbindgen.toml src/ffi.rs -o include/lmp.h
// Don't modify manually.
'''
sys_includes = ["stdint.h"]
no_includes = true
+92 −0
Original line number Diff line number Diff line
#pragma once

// This file is autogenerated by:
//   cbindgen --config cbindgen.toml src/ffi.rs -o include/lmp.h
// Don't modify manually.

#include <stdint.h>

/// Link Manager callbacks
struct LinkManagerOps {
  void* user_pointer;
  uint16_t (*get_handle)(void* user, const uint8_t (*address)[6]);
  void (*get_address)(void* user, uint16_t handle, uint8_t (*result)[6]);
  uint64_t (*extended_features)(void* user, uint8_t features_page);
  void (*send_hci_event)(void* user, const uint8_t* data, uintptr_t len);
  void (*send_lmp_packet)(void* user, const uint8_t (*to)[6],
                          const uint8_t* data, uintptr_t len);
};

extern "C" {

/// Create a new link manager instance
/// # Arguments
/// * `ops` - Function callbacks required by the link manager
const LinkManager* link_manager_create(LinkManagerOps ops);

/// Register a new link with a peer inside the link manager
/// # Arguments
/// * `lm` - link manager pointer
/// * `peer` - peer address as array of 6 bytes
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointer
/// - `peer` must be valid for reads for 6 bytes
bool link_manager_add_link(const LinkManager* lm, const uint8_t (*peer)[6]);

/// Unregister a link with a peer inside the link manager
/// Returns true if successful
/// # Arguments
/// * `lm` - link manager pointer
/// * `peer` - peer address as array of 6 bytes
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointer
/// - `peer` must be valid for reads for 6 bytes
bool link_manager_remove_link(const LinkManager* lm, const uint8_t (*peer)[6]);

/// Run the Link Manager procedures
/// # Arguments
/// * `lm` - link manager pointer
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointer
void link_manager_tick(const LinkManager* lm);

/// Process an HCI packet with the link manager
/// Returns true if successful
/// # Arguments
/// * `lm` - link manager pointer
/// * `data` - HCI packet data
/// * `len` - HCI packet len
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointer
/// - `data` must be valid for reads of len `len`
bool link_manager_ingest_hci(const LinkManager* lm, const uint8_t* data,
                             uintptr_t len);

/// Process an LMP packet from a peer with the link manager
/// Returns true if successful
/// # Arguments
/// * `lm` - link manager pointer
/// * `from` - Address of peer as array of 6 bytes
/// * `data` - HCI packet data
/// * `len` - HCI packet len
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointers
/// - `from` must be valid pointer for reads for 6 bytes
/// - `data` must be valid for reads of len `len`
bool link_manager_ingest_lmp(const LinkManager* lm, const uint8_t (*from)[6],
                             const uint8_t* data, uintptr_t len);

/// Deallocate the link manager instance
/// # Arguments
/// * `lm` - link manager pointer
/// # Safety
/// - This should be called from the thread of creation
/// - `lm` must be a valid pointers and must not be reused afterwards
void link_manager_destroy(const LinkManager* lm);

}  // extern "C"
Loading