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

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

Merge changes from topic "Bug282931760"

* changes:
  Populate bd_addr for callback when RNR fails
  test: Add bt_host_test_bta::bta_dm_sp_cback
parents d71dbab7 8c1566e3
Loading
Loading
Loading
Loading
+30 −18
Original line number Diff line number Diff line
@@ -2514,7 +2514,7 @@ static void bta_dm_authentication_complete_cback(
static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event,
                                   tBTM_SP_EVT_DATA* p_data) {
  tBTM_STATUS status = BTM_CMD_STARTED;
  tBTA_DM_SEC sec_event;
  tBTA_DM_SEC sec_event = {};
  tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;

  APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
@@ -2559,10 +2559,19 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event,
        break;
      }

      // TODO PleaseFix: This assignment only works with event
      // BTM_SP_KEY_NOTIF_EVT
      bta_dm_cb.num_val = sec_event.key_notif.passkey =
          p_data->key_notif.passkey;

      if (BTM_SP_CFM_REQ_EVT == event) {
        /* Due to the switch case falling through below to
           BTM_SP_KEY_NOTIF_EVT,
           copy these values into key_notif from cfm_req */
        sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
        dev_class_copy(sec_event.key_notif.dev_class,
                       p_data->cfm_req.dev_class);
        bd_name_copy(sec_event.key_notif.bd_name, p_data->cfm_req.bd_name);
        /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
           call remote name request using values from cfm_req */
        if (p_data->cfm_req.bd_name[0] == 0) {
@@ -2573,23 +2582,20 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event,
          bta_dm_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req;
          bta_dm_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req;

          BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
                                p_data->cfm_req.dev_class);
          if ((BTM_ReadRemoteDeviceName(
          dev_class_copy(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
          {
            const tBTM_STATUS btm_status = BTM_ReadRemoteDeviceName(
                p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
                  BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
            return BTM_CMD_STARTED;
          APPL_TRACE_WARNING(
              " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
        } else {
          /* Due to the switch case falling through below to
             BTM_SP_KEY_NOTIF_EVT,
             copy these values into key_notif from cfm_req */
          sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
          BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
                                p_data->cfm_req.dev_class);
          strlcpy((char*)sec_event.key_notif.bd_name,
                  (char*)p_data->cfm_req.bd_name, BD_NAME_LEN + 1);
                BT_TRANSPORT_BR_EDR);
            switch (btm_status) {
              case BTM_CMD_STARTED:
                return btm_status;
              default:
                // NOTE: This will issue callback on this failure path
                LOG_WARN("Failed to start Remote Name Request btm_status:%s",
                         btm_status_text(btm_status).c_str());
            };
          }
        }
      }

@@ -4781,6 +4787,12 @@ tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& bd_addr) {
  return ::bta_dm_determine_discovery_transport(bd_addr);
}

tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data) {
  return ::bta_dm_sp_cback(event, p_data);
}

void btm_set_local_io_caps(uint8_t io_caps) { ::btm_local_io_caps = io_caps; }

}  // namespace testing
}  // namespace legacy
}  // namespace bluetooth
+188 −6
Original line number Diff line number Diff line
@@ -16,10 +16,13 @@

#include <base/functional/bind.h>
#include <base/location.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <chrono>
#include <iostream>
#include <memory>
#include <string>

#include "bta/dm/bta_dm_int.h"
#include "bta/hf_client/bta_hf_client_int.h"
@@ -29,6 +32,8 @@
#include "btif/include/stack_manager.h"
#include "common/message_loop_thread.h"
#include "osi/include/compat.h"
#include "stack/include/bt_dev_class.h"
#include "stack/include/bt_name.h"
#include "stack/include/btm_status.h"
#include "test/common/main_handler.h"
#include "test/common/mock_functions.h"
@@ -36,9 +41,11 @@
#include "test/mock/mock_osi_alarm.h"
#include "test/mock/mock_osi_allocator.h"
#include "test/mock/mock_stack_acl.h"
#include "test/mock/mock_stack_btm_inq.h"
#include "test/mock/mock_stack_btm_sec.h"

using namespace std::chrono_literals;
using ::testing::ElementsAre;

extern struct btm_client_interface_t btm_client_interface;

@@ -50,12 +57,9 @@ namespace {
constexpr uint8_t kUnusedTimer = BTA_ID_MAX;
const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
const RawAddress kRawAddress2({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
constexpr char kRemoteName[] = "TheRemoteName";
const DEV_CLASS kDeviceClass = {0x11, 0x22, 0x33};

const char* test_flags[] = {
    "INIT_logging_debug_enabled_for_all=true",
    nullptr,
};
constexpr char kRemoteName[] = "TheRemoteName";

bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) { return true; }
void bta_dm_search_sm_disable() { bta_sys_deregister(BTA_ID_DM_SEARCH); }
@@ -69,7 +73,6 @@ class BtaDmTest : public testing::Test {
 protected:
  void SetUp() override {
    reset_mock_function_count_map();
    bluetooth::common::InitFlags::Load(test_flags);
    fake_osi_ = std::make_unique<test::fake::FakeOsi>();

    main_thread_start_up();
@@ -226,6 +229,10 @@ void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p);
tBT_TRANSPORT bta_dm_determine_discovery_transport(
    const RawAddress& remote_bd_addr);

void btm_set_local_io_caps(uint8_t io_caps);

tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);

}  // namespace testing
}  // namespace legacy
}  // namespace bluetooth
@@ -516,3 +523,178 @@ TEST_F(BtaDmTest, bta_dm_remote_name_cmpl) {
  bta_dm_remote_name_cmpl(&msg);
  ASSERT_EQ(1, get_func_call_count("BTM_InqDbRead"));
}

TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithName) {
  constexpr uint32_t kNumVal = 1234;
  static bool callback_sent = false;
  static tBTA_DM_SP_CFM_REQ cfm_req{};
  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
    callback_sent = true;
    cfm_req = p_data->cfm_req;
  });

  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);

  tBTM_SP_EVT_DATA data = {
      .cfm_req =
          {
              // tBTM_SP_CFM_REQ
              .bd_addr = kRawAddress,
              .dev_class = {},
              .bd_name = {},
              .num_val = kNumVal,
              .just_works = false,
              .loc_auth_req = BTM_AUTH_SP_YES,
              .rmt_auth_req = BTM_AUTH_SP_YES,
              .loc_io_caps = BTM_IO_CAP_NONE,
              .rmt_io_caps = BTM_IO_CAP_NONE,
          },
  };
  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);
  bd_name_copy(data.cfm_req.bd_name, kRemoteName);

  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
                BTM_SP_CFM_REQ_EVT, &data)));
  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
  ASSERT_TRUE(callback_sent);

  ASSERT_EQ(kRawAddress, cfm_req.bd_addr);
  ASSERT_THAT(cfm_req.dev_class,
              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
  ASSERT_STREQ(kRemoteName, reinterpret_cast<const char*>(cfm_req.bd_name));
  ASSERT_EQ(kNumVal, cfm_req.num_val);
  ASSERT_EQ(false, cfm_req.just_works);
  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.loc_auth_req);
  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.rmt_auth_req);
  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.loc_io_caps);
  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.rmt_io_caps);
}

TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRSuccess) {
  constexpr uint32_t kNumVal = 1234;
  static bool callback_sent = false;
  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName.body =
      [](const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
         tBT_TRANSPORT transport) { return BTM_CMD_STARTED; };

  static tBTA_DM_SP_CFM_REQ cfm_req{};
  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
    callback_sent = true;
    cfm_req = p_data->cfm_req;
  });

  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);

  tBTM_SP_EVT_DATA data = {
      .cfm_req =
          {
              // tBTM_SP_CFM_REQ
              .bd_addr = kRawAddress,
              .dev_class = {},
              .bd_name = {0},
              .num_val = kNumVal,
              .just_works = false,
              .loc_auth_req = BTM_AUTH_SP_YES,
              .rmt_auth_req = BTM_AUTH_SP_YES,
              .loc_io_caps = BTM_IO_CAP_NONE,
              .rmt_io_caps = BTM_IO_CAP_NONE,
          },
  };
  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);

  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
                BTM_SP_CFM_REQ_EVT, &data)));
  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
  ASSERT_FALSE(callback_sent);

  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName = {};
}

TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRFail) {
  constexpr uint32_t kNumVal = 1234;
  static bool callback_sent = false;
  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName.body =
      [](const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
         tBT_TRANSPORT transport) { return BTM_SUCCESS; };

  static tBTA_DM_SP_CFM_REQ cfm_req{};
  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
    callback_sent = true;
    cfm_req = p_data->cfm_req;
  });

  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);

  tBTM_SP_EVT_DATA data = {
      .cfm_req =
          {
              // tBTM_SP_CFM_REQ
              .bd_addr = kRawAddress,
              .dev_class = {},
              .bd_name = {0},
              .num_val = kNumVal,
              .just_works = false,
              .loc_auth_req = BTM_AUTH_SP_YES,
              .rmt_auth_req = BTM_AUTH_SP_YES,
              .loc_io_caps = BTM_IO_CAP_NONE,
              .rmt_io_caps = BTM_IO_CAP_NONE,
          },
  };
  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);

  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
                BTM_SP_CFM_REQ_EVT, &data)));
  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
  ASSERT_TRUE(callback_sent);

  ASSERT_EQ(kRawAddress, cfm_req.bd_addr);
  ASSERT_THAT(cfm_req.dev_class,
              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
  ASSERT_EQ(kNumVal, cfm_req.num_val);
  ASSERT_EQ(false, cfm_req.just_works);
  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.loc_auth_req);
  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.rmt_auth_req);
  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.loc_io_caps);
  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.rmt_io_caps);

  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName = {};
}

TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_KEY_NOTIF_EVT) {
  constexpr uint32_t kPassKey = 1234;
  static bool callback_sent = false;
  static tBTA_DM_SP_KEY_NOTIF key_notif{};
  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
    callback_sent = true;
    key_notif = p_data->key_notif;
  });
  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);

  tBTM_SP_EVT_DATA data = {
      .key_notif =
          {
              // tBTM_SP_KEY_NOTIF
              .bd_addr = kRawAddress,
              .dev_class = {},
              .bd_name = {},
              .passkey = kPassKey,
          },
  };
  dev_class_copy(data.key_notif.dev_class, kDeviceClass);
  bd_name_copy(data.key_notif.bd_name, kRemoteName);

  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
                BTM_SP_KEY_NOTIF_EVT, &data)));
  ASSERT_EQ(kPassKey, bta_dm_cb.num_val);
  ASSERT_TRUE(callback_sent);

  ASSERT_EQ(kRawAddress, key_notif.bd_addr);
  ASSERT_THAT(key_notif.dev_class,
              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
  ASSERT_STREQ(kRemoteName, reinterpret_cast<const char*>(key_notif.bd_name));
  ASSERT_EQ(kPassKey, key_notif.passkey);
}
+6 −0
Original line number Diff line number Diff line
@@ -123,6 +123,12 @@ inline constexpr DEV_CLASS kDevClassEmpty = {};
  }

#ifdef __cplusplus
inline void dev_class_copy(DEV_CLASS& dst, const DEV_CLASS& src) {
  dst[0] = src[0];
  dst[1] = src[1];
  dst[2] = src[2];
}

#include <sstream>
inline std::string dev_class_text(const DEV_CLASS& dev_class) {
  std::ostringstream oss;
+4 −0
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@ typedef uint8_t tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1];
inline constexpr tBTM_BD_NAME kBtmBdNameEmpty = {};
constexpr size_t kBdNameLength = static_cast<size_t>(BD_NAME_LEN);

inline size_t bd_name_copy(BD_NAME bd_name_dest, const char* src) {
  return strlcpy(reinterpret_cast<char*>(bd_name_dest), const_cast<char*>(src),
                 kBdNameLength + 1);
}
inline size_t bd_name_copy(BD_NAME bd_name_dest, const BD_NAME bd_name_src) {
  return strlcpy(reinterpret_cast<char*>(bd_name_dest),
                 reinterpret_cast<const char*>(bd_name_src), kBdNameLength + 1);
+207 −78

File changed.

Preview size limit exceeded, changes collapsed.

Loading