blob: 68a741b0cfffecda13cd0cdfedabeb5f68aa56da [file] [log] [blame]
/*
*
* Copyright 2020 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.
*
*/
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <iomanip>
#include <iostream>
#include <map>
#include <vector>
#include "btif/include/btif_hh.h"
#include "hci/include/hci_layer.h"
#include "hci/include/hci_packet_factory.h"
#include "internal_include/stack_config.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sco.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_hci_link_interface.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/hcidefs.h"
#include "stack/l2cap/l2c_int.h"
#include "test/mock/mock_hcic_hcicmds.h"
#include "types/raw_address.h"
namespace mock = test::mock::hcic_hcicmds;
extern tBTM_CB btm_cb;
uint8_t appl_trace_level = BT_TRACE_LEVEL_VERBOSE;
btif_hh_cb_t btif_hh_cb;
tL2C_CB l2cb;
const hci_t* hci_layer_get_interface() { return nullptr; }
void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
const std::string kSmpOptions("mock smp options");
bool get_trace_config_enabled(void) { return false; }
bool get_pts_avrcp_test(void) { return false; }
bool get_pts_secure_only_mode(void) { return false; }
bool get_pts_conn_updates_disabled(void) { return false; }
bool get_pts_crosskey_sdp_disable(void) { return false; }
const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
int get_pts_smp_failure_case(void) { return 123; }
config_t* get_all(void) { return nullptr; }
const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
stack_config_t mock_stack_config{
.get_trace_config_enabled = get_trace_config_enabled,
.get_pts_avrcp_test = get_pts_avrcp_test,
.get_pts_secure_only_mode = get_pts_secure_only_mode,
.get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
.get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
.get_pts_smp_options = get_pts_smp_options,
.get_pts_smp_failure_case = get_pts_smp_failure_case,
.get_all = get_all,
};
const stack_config_t* stack_config_get_interface(void) {
return &mock_stack_config;
}
std::map<std::string, int> mock_function_count_map;
extern bool MOCK_bluetooth_shim_is_gd_acl_enabled_;
namespace {
using testing::_;
using testing::DoAll;
using testing::NotNull;
using testing::Pointee;
using testing::Return;
using testing::SaveArg;
using testing::SaveArgPointee;
using testing::StrEq;
using testing::StrictMock;
using testing::Test;
std::string Hex16(int n) {
std::ostringstream oss;
oss << "0x" << std::hex << std::setw(4) << std::setfill('0') << n;
return oss.str();
}
class StackBtmTest : public Test {
public:
protected:
void SetUp() override { mock_function_count_map.clear(); }
void TearDown() override {}
};
TEST_F(StackBtmTest, GlobalLifecycle) {
get_btm_client_interface().lifecycle.btm_init();
get_btm_client_interface().lifecycle.btm_free();
}
TEST_F(StackBtmTest, DynamicLifecycle) {
auto* btm = new tBTM_CB();
delete btm;
}
TEST_F(StackBtmTest, InformClientOnConnectionSuccess) {
MOCK_bluetooth_shim_is_gd_acl_enabled_ = true;
get_btm_client_interface().lifecycle.btm_init();
RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
btm_acl_connected(bda, 2, HCI_SUCCESS, false);
ASSERT_EQ(static_cast<size_t>(1),
mock_function_count_map.count("BTA_dm_acl_up"));
get_btm_client_interface().lifecycle.btm_free();
}
TEST_F(StackBtmTest, NoInformClientOnConnectionFail) {
MOCK_bluetooth_shim_is_gd_acl_enabled_ = true;
get_btm_client_interface().lifecycle.btm_init();
RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
btm_acl_connected(bda, 2, HCI_ERR_NO_CONNECTION, false);
ASSERT_EQ(static_cast<size_t>(0),
mock_function_count_map.count("BTA_dm_acl_up"));
get_btm_client_interface().lifecycle.btm_free();
}
TEST_F(StackBtmTest, default_packet_type) {
get_btm_client_interface().lifecycle.btm_init();
btm_cb.acl_cb_.SetDefaultPacketTypeMask(0x4321);
ASSERT_EQ(0x4321, btm_cb.acl_cb_.DefaultPacketTypes());
get_btm_client_interface().lifecycle.btm_free();
}
TEST_F(StackBtmTest, change_packet_type) {
int cnt = 0;
get_btm_client_interface().lifecycle.btm_init();
btm_cb.acl_cb_.SetDefaultPacketTypeMask(0xffff);
ASSERT_EQ(0xffff, btm_cb.acl_cb_.DefaultPacketTypes());
// Create connection
RawAddress bda({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
btm_acl_created(bda, 0x123, HCI_ROLE_CENTRAL, BT_TRANSPORT_BR_EDR);
uint64_t features = 0xffffffffffffffff;
acl_process_supported_features(0x123, features);
mock::btsnd_hcic_change_conn_type = {};
uint16_t pkt_types = 0x55aa;
btm_set_packet_types_from_address(bda, pkt_types);
ASSERT_EQ(++cnt, mock_function_count_map["btsnd_hcic_change_conn_type"]);
ASSERT_EQ(0x123, mock::btsnd_hcic_change_conn_type.handle);
ASSERT_EQ(Hex16(0x4400 | HCI_PKT_TYPES_MASK_DM1),
Hex16(mock::btsnd_hcic_change_conn_type.packet_types));
mock::btsnd_hcic_change_conn_type = {};
btm_set_packet_types_from_address(bda, 0xffff);
ASSERT_EQ(++cnt, mock_function_count_map["btsnd_hcic_change_conn_type"]);
ASSERT_EQ(0x123, mock::btsnd_hcic_change_conn_type.handle);
ASSERT_EQ(Hex16(0xcc00 | HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1),
Hex16(mock::btsnd_hcic_change_conn_type.packet_types));
mock::btsnd_hcic_change_conn_type = {};
btm_set_packet_types_from_address(bda, 0x0);
// NOTE: The call should not be executed with no bits set
ASSERT_EQ(0x0, mock::btsnd_hcic_change_conn_type.handle);
ASSERT_EQ(Hex16(0x0), Hex16(mock::btsnd_hcic_change_conn_type.packet_types));
get_btm_client_interface().lifecycle.btm_free();
}
TEST(ScoTest, make_sco_packet) {
std::vector<uint8_t> data = {10, 20, 30};
uint16_t handle = 0xab;
BT_HDR* p = btm_sco_make_packet(data, handle);
ASSERT_EQ(p->event, BT_EVT_TO_LM_HCI_SCO);
ASSERT_EQ(p->len, 3 + data.size());
ASSERT_EQ(p->data[0], 0xab);
ASSERT_EQ(p->data[1], 0);
ASSERT_EQ(p->data[2], 3);
ASSERT_EQ(p->data[3], 10);
ASSERT_EQ(p->data[4], 20);
ASSERT_EQ(p->data[5], 30);
osi_free(p);
}
} // namespace