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

Commit e9a8dd7c authored by Chris Manton's avatar Chris Manton Committed by Gerrit Code Review
Browse files

Merge "testable: headless: Add discovery and scan module"

parents 98746056 41a17b9f
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -7,20 +7,49 @@ package {
    default_applicable_licenses: ["system_bt_license"],
}

cc_test {
sh_binary {
  name: "headless_build_timestamp",
  host_supported: true,
  src: "tools/build_timestamp.sh",
}

genrule {
  name : "HeadlessBuildTimestamp",
  tools: [
    "headless_build_timestamp",
  ],
  cmd: "$(location headless_build_timestamp) > $(out)",
  out: [
    "build_timestamp.h"
  ],
}

cc_binary {
    name: "bt_headless",
    test_suites: ["device-tests"],
    defaults: [
        "fluoride_defaults",
        "mts_defaults",
    ],
    cflags: [
        "-Wno-date-time",
        "-Wall",
        "-Wextra",
        "-Werror",
    ],
    generated_headers: [
        "HeadlessBuildTimestamp",
    ],
    srcs: [
        "bt_property.cc",
        "connect/connect.cc",
        "get_options.cc",
        "headless.cc",
        "log.cc",
        "main.cc",
        "messenger.cc",
        "pairing/pairing.cc",
        "discovery/discovery.cc",
        "dumpsys/dumpsys.cc",
        "scan/scan.cc",
        "sdp/sdp.cc",
        "sdp/sdp_db.cc",
        "nop/nop.cc",
+15 −2
Original line number Diff line number Diff line
@@ -15,10 +15,23 @@ Build: Source, lunch and build as typical Android target for selected device and
    make bt_headless

Install: Push the binary to an executable area on target device.
    adb push out/target/product/<device..arch>/bt_headless/bt_headless /data/data/.
    adb push ${ANDROID_PRODUCT_OUT}/system/bin/bt_headless /data/data/.

Prepare: Ensure the system is queisced to prevent resource conflicts from the bluetooth process.
    adb shell stop

Run: Script or directly execute the target file.
    adb shell /data/data/bt_headless --flags=INIT_logging_debug_enabled_for_all=true,INIT_gd_acl=true nop
    adb shell /data/data/bt_headless --loop=10 nop
    ```
    [1102/174836.145418:INFO:btif_config_cache.cc(67)] BtifConfigCache, capacity: 10000
    Nop loop:0
    Nop loop:1
    Nop loop:2
    Nop loop:3
    Nop loop:4
    Nop loop:5
    Nop loop:6
    Nop loop:7
    Nop loop:8
    Nop loop:9
    ```
+125 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "bt_headless_property"

#include "test/headless/bt_property.h"

#include "base/logging.h"  // LOG() stdout and android log
#include "btif/include/btif_api.h"
#include "osi/include/log.h"  // android log only
#include "stack/include/sdp_api.h"
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
#include "test/headless/interface.h"
#include "test/headless/log.h"
#include "test/headless/sdp/sdp.h"
#include "test/headless/stopwatch.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"

using namespace bluetooth::test::headless;
using namespace std::chrono_literals;

namespace bluetooth {
namespace test {
namespace headless {

void process_property(const RawAddress& bd_addr, const bt_property_t* prop) {
  LOG_INFO("%s bt_property type:%d len:%d val:%p", STR(bd_addr), prop->type,
           prop->len, prop->val);
  switch (prop->type) {
    case BT_PROPERTY_BDNAME: {
      ASSERT(prop->len >= 0);
      std::string name(static_cast<const char*>(prop->val),
                       static_cast<size_t>(prop->len));
      LOG_CONSOLE("BT_PROPERTY_BDNAME  NAME:%s", name.c_str());
    } break;
    case BT_PROPERTY_BDADDR:
      LOG_CONSOLE("BT_PROPERTY_BDADDR");
      break;
    case BT_PROPERTY_UUIDS: {
      const size_t remainder = prop->len % sizeof(bluetooth::Uuid);
      ASSERT(remainder == 0);
      bluetooth::Uuid* uuid = reinterpret_cast<bluetooth::Uuid*>(prop->val);
      for (int len = prop->len; len > 0; len -= sizeof(*uuid)) {
        LOG_CONSOLE("BT_PROPERTY_UUIDS  UUID:%s", uuid->ToString().c_str());
        uuid++;
      }
    } break;
    case BT_PROPERTY_CLASS_OF_DEVICE: {
      ASSERT(prop->len == 4);
      uint32_t cod = *(reinterpret_cast<uint32_t*>(prop->val));
      LOG_CONSOLE("BT_PROPERTY_CLASS_OF_DEVICE  0x%04x", cod);
    } break;
    case BT_PROPERTY_TYPE_OF_DEVICE: {
      ASSERT(prop->len == 4);
      uint32_t devtype = *(reinterpret_cast<uint32_t*>(prop->val));
      LOG_CONSOLE("BT_PROPERTY_TYPE_OF_DEVICE  0x%04x", devtype);
    } break;
    case BT_PROPERTY_SERVICE_RECORD:
      LOG_CONSOLE("BT_PROPERTY_SERVICE_RECORD");
      break;
    case BT_PROPERTY_ADAPTER_SCAN_MODE:
      LOG_CONSOLE("BT_PROPERTY_ADAPTER_SCAN_MODE");
      break;
    case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
      LOG_CONSOLE("BT_PROPERTY_ADAPTER_BONDED_DEVICES");
      break;
    case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
      LOG_CONSOLE("BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT");
      break;
    case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
      LOG_CONSOLE("BT_PROPERTY_REMOTE_FRIENDLY_NAME");
      break;
    case BT_PROPERTY_REMOTE_RSSI:
      LOG_CONSOLE("BT_PROPERTY_REMOTE_RSSI");
      break;
    case BT_PROPERTY_REMOTE_VERSION_INFO:
      LOG_CONSOLE("BT_PROPERTY_REMOTE_VERSION_INFO");
      break;
    case BT_PROPERTY_LOCAL_LE_FEATURES:
      LOG_CONSOLE("BT_PROPERTY_LOCAL_LE_FEATURES");
      break;
    case BT_PROPERTY_LOCAL_IO_CAPS:
      LOG_CONSOLE("BT_PROPERTY_LOCAL_IO_CAPS");
      break;
    case BT_PROPERTY_LOCAL_IO_CAPS_BLE:
      LOG_CONSOLE("BT_PROPERTY_LOCAL_IO_CAPS_BLE");
      break;
    case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER:
      LOG_CONSOLE("BT_PROPERTY_DYNAMIC_AUDIO_BUFFER");
      break;
    case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER:
      LOG_CONSOLE("BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER");
      break;
    case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
      LOG_CONSOLE("BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER");
      break;
    default: {
      LOG_CONSOLE("Unable to find BT property bd_addr:%s type:%d ptr:%p",
                  STR(bd_addr), prop->type, prop);
      const uint8_t* p = reinterpret_cast<const uint8_t*>(prop);
      for (size_t i = 0; i < sizeof(bt_property_t); i++, p++) {
        LOG_CONSOLE("  %p:0x%02x", p, *p);
      }
    } break;
  }
}

}  // namespace headless
}  // namespace test
}  // namespace bluetooth
+14 −0
Original line number Diff line number Diff line


#pragma once

#include "include/hardware/bluetooth.h"

namespace bluetooth {
namespace test {
namespace headless {

void process_property(const RawAddress& bd_addr, const bt_property_t* prop);
}
}  // namespace test
}  // namespace bluetooth
+29 −29
Original line number Diff line number Diff line
@@ -38,33 +38,34 @@
#include "types/raw_address.h"

const stack_manager_t* stack_manager_get_interface();
extern bt_interface_t bluetoothInterface;

void power_mode_callback(const RawAddress& p_bda, tBTM_PM_STATUS status,
                         uint16_t value, tHCI_STATUS hci_status) {
void power_mode_callback([[maybe_unused]] const RawAddress& p_bda,
                         [[maybe_unused]] tBTM_PM_STATUS status,
                         [[maybe_unused]] uint16_t value,
                         [[maybe_unused]] tHCI_STATUS hci_status) {
  fprintf(stdout, "Got callback\n");
};

namespace connect {
std::promise<acl_state_changed_params_t> acl_state_changed_promise;

void callback_interface(interface_data_t data) {
  if (data.name == "acl_state_changed") {
    LOG(INFO) << "Received acl state changed";
    acl_state_changed_params_t p{
        .status = BT_STATUS_SUCCESS,
        .remote_bd_addr = nullptr,
        .state = BT_ACL_STATE_CONNECTED,
    };
    acl_state_changed_promise.set_value(p);
    return;
}  // namespace connect

void callback_interface(callback_data_t* data) {
  if (data->Name() == "acl_state_changed") {
    LOG(INFO) << "Received acl state changed discovery";
    auto params = static_cast<acl_state_changed_params_t*>(data);
    acl_state_changed_params_t p(*params);
    connect::acl_state_changed_promise.set_value(p);
  }
  LOG(ERROR) << "Received unexpected interface callback";
}

namespace {

int do_connect(unsigned int num_loops, const RawAddress& bd_addr,
               std::list<std::string> options) {
int do_connect([[maybe_unused]] unsigned int num_loops,
               [[maybe_unused]] const RawAddress& bd_addr,
               [[maybe_unused]] std::list<std::string> options) {
  int disconnect_wait_time{0};

  if (options.size() != 0) {
@@ -79,19 +80,20 @@ int do_connect(unsigned int num_loops, const RawAddress& bd_addr,

  headless_add_callback("acl_state_changed", callback_interface);

  acl_state_changed_promise = std::promise<acl_state_changed_params_t>();
  auto future = acl_state_changed_promise.get_future();
  connect::acl_state_changed_promise =
      std::promise<acl_state_changed_params_t>();
  auto future = connect::acl_state_changed_promise.get_future();

  fprintf(stdout, "Creating connection to:%s\n", bd_addr.ToString().c_str());
  LOG(INFO) << "Creating classic connection to " << bd_addr.ToString();
  acl_create_classic_connection(bd_addr, false, false);

  acl_state_changed_params_t result = future.get();
  fprintf(stdout, "Connected created to:%s result:%s[%u]\n",
          bd_addr.ToString().c_str(), bt_status_text(result.status).c_str(),
          result.status);
  acl_state_changed_promise = std::promise<acl_state_changed_params_t>();
  future = acl_state_changed_promise.get_future();
  auto result = future.get();
  LOG_CONSOLE("Connected created %s", result.ToString().c_str());

  connect::acl_state_changed_promise =
      std::promise<acl_state_changed_params_t>();
  future = connect::acl_state_changed_promise.get_future();

  uint64_t connect = std::chrono::duration_cast<std::chrono::milliseconds>(
                         std::chrono::system_clock::now().time_since_epoch())
@@ -103,21 +105,19 @@ int do_connect(unsigned int num_loops, const RawAddress& bd_addr,

  if (disconnect_wait_time == 0) {
    fprintf(stdout, "Waiting to disconnect from supervision timeout\n");
    result = future.get();
    auto result = future.get();
    uint64_t disconnect =
        std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch())
            .count();

    fprintf(stdout, "Disconnected after:%" PRId64 "ms from:%s result:%s[%u]\n",
    LOG_CONSOLE("Disconnected after:%" PRId64 "ms from:%s result:%s[%u]\n",
                disconnect - connect, bd_addr.ToString().c_str(),
                bt_status_text(result.status).c_str(), result.status);

    headless_remove_callback("acl_state_changed", callback_interface);
  } else {
    fprintf(stdout, "Waiting %d seconds to just shutdown\n",
            disconnect_wait_time);
    sleep(disconnect_wait_time);
    bluetoothInterface.dump(1, nullptr);
    bluetoothInterface.cleanup();
  }
Loading