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

Commit 3e2d2b79 authored by Chris Manton's avatar Chris Manton
Browse files

Fix for hid disconnect with unknown channel

Also introduce net_test_stack_hid
And update mocks to allow functional replacement

Bug: 181199209
Test: gd/cert/run
Tag: #refactor
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: Iab4ac55477d2d98d52d7b77aee19b4172c63e4eb
parent f63096f1
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -805,3 +805,51 @@ cc_test {
        },
    },
}

cc_test {
    name: "net_test_stack_hid",
    test_suites: ["device-tests"],
    host_supported: true,
    defaults: ["fluoride_defaults"],
    local_include_dirs: [
        "include",
        "test/common",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
    ],
    srcs: crypto_toolbox_srcs + [
        ":TestStackL2cap",
        ":TestStackSdp",
        ":TestStackBtm",
        ":TestStubLegacyTrace",
        "hid/hidd_api.cc",
        "hid/hidd_conn.cc",
        "hid/hidh_api.cc",
        "hid/hidh_conn.cc",
        "test/hid/stack_hid_test.cc",
    ],
    static_libs: [
        "libbt-common",
        "libbt-protos-lite",
        "libbtdevice",
        "libbte",
        "libgmock",
        "liblog",
        "libosi",
    ],
    shared_libs: [
        "libcrypto",
        "libprotobuf-cpp-lite",
    ],
    sanitize: {
        address: true,
        all_undefined: true,
        cfi: true,
        integer_overflow: true,
        scs: true,
        diag: {
            undefined : true
        },
    },
}
+6 −0
Original line number Diff line number Diff line
@@ -270,6 +270,12 @@ static void hidh_try_repage(uint8_t dhandle) {

static void hidh_on_l2cap_error(uint16_t l2cap_cid, uint16_t result) {
  auto dhandle = find_conn_by_cid(l2cap_cid);
  if (dhandle == kHID_HOST_MAX_DEVICES) {
    LOG_WARN("Received error for unknown device cid:0x%04x reason:%s",
             l2cap_cid,
             hci_reason_code_text(to_hci_reason_code(result)).c_str());
    return;
  }

  hidh_conn_disconnect(dhandle);

+77 −0
Original line number Diff line number Diff line
/*
 *  Copyright 2021 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 <cstring>
#include <map>

#include "common/message_loop_thread.h"
#include "osi/include/log.h"
#include "stack/hid/hidh_int.h"
#include "stack/include/hci_error_code.h"
#include "test/mock/mock_stack_l2cap_api.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"

std::map<std::string, int> mock_function_count_map;

bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
tHCI_REASON btm_get_acl_disc_reason_code(void) { return HCI_SUCCESS; }

bool BTM_IsAclConnectionUp(const RawAddress& remote_bda,
                           tBT_TRANSPORT transport) {
  return true;
}
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;

class StackHidTest : public Test {
 public:
 protected:
  void SetUp() override { mock_function_count_map.clear(); }
  void TearDown() override {}
};

TEST_F(StackHidTest, disconnect_bad_cid) {
  tL2CAP_APPL_INFO l2cap_callbacks;

  test::mock::stack_l2cap_api::L2CA_Register2.body =
      [&l2cap_callbacks](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                         bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                         uint16_t my_mtu, uint16_t required_remote_mtu,
                         uint16_t sec_level) {
        l2cap_callbacks = p_cb_info;
        return psm;
      };

  tHID_STATUS status = hidh_conn_reg();
  ASSERT_EQ(HID_SUCCESS, status);

  l2cap_callbacks.pL2CA_Error_Cb(123, 456);
}

}  // namespace
+19 −0
Original line number Diff line number Diff line
@@ -117,4 +117,23 @@ filegroup {
  ],
}

filegroup {
  name: "TestStackSdp",
  srcs: [
      "mock/mock_stack_sdp*.cc",
  ],
}

filegroup {
  name: "TestStackBtm",
  srcs: [
      "mock/mock_stack_btm*.cc",
  ],
}

filegroup {
  name: "TestStubLegacyTrace",
  srcs: [
      "stub/legacy_trace.cc",
  ],
}
+0 −177
Original line number Diff line number Diff line
/*
 * Copyright 2021 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.
 */

/*
 * Generated mock file from original source file
 *   Functions generated:33
 */

#include <map>
#include <string>

extern std::map<std::string, int> mock_function_count_map;

#include <cstdint>
#include "stack/include/l2c_api.h"
#include "types/raw_address.h"

#ifndef UNUSED_ATTR
#define UNUSED_ATTR
#endif

bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id,
                                std::vector<uint16_t>& accepted_lcids,
                                uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_DisconnectLECocReq(uint16_t cid) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_DisconnectReq(uint16_t cid) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
                          uint8_t* p_chnl_mask) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_IsLinkEstablished(const RawAddress& bd_addr,
                            tBT_TRANSPORT transport) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bda,
                                      std::vector<uint16_t>& lcids,
                                      tL2CAP_LE_CFG_INFO* p_cfg) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_RegisterFixedChannel(uint16_t fixed_cid,
                               tL2CAP_FIXED_CHNL_REG* p_freg) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
                                 tBT_TRANSPORT transport) {
  mock_function_count_map[__func__]++;
  return false;
}
bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) {
  mock_function_count_map[__func__]++;
  return false;
}
std::vector<uint16_t> L2CA_ConnectCreditBasedReq(uint16_t psm,
                                                 const RawAddress& p_bd_addr,
                                                 tL2CAP_LE_CFG_INFO* p_cfg) {
  mock_function_count_map[__func__]++;
  std::vector<uint16_t> v;
  return v;
}
tBT_TRANSPORT l2c_get_transport_from_fixed_cid(uint16_t fixed_cid) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_AllocateLePSM(void) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
                              tL2CAP_LE_CFG_INFO* p_cfg, uint16_t sec_level) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_ConnectReq2(uint16_t psm, const RawAddress& p_bd_addr,
                          uint16_t sec_level) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                       bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                       uint16_t my_mtu, uint16_t required_remote_mtu) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_Register2(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                        bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                        uint16_t my_mtu, uint16_t required_remote_mtu,
                        uint16_t sec_level) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                            uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda,
                                BT_HDR* p_buf) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) {
  mock_function_count_map[__func__]++;
  return 0;
}
uint8_t L2CA_SetTraceLevel(uint8_t new_level) {
  mock_function_count_map[__func__]++;
  return 0;
}
void L2CA_Deregister(uint16_t psm) { mock_function_count_map[__func__]++; }
void L2CA_DeregisterLECoc(uint16_t psm) { mock_function_count_map[__func__]++; }
void L2CA_FreeLePSM(uint16_t psm) { mock_function_count_map[__func__]++; }
Loading