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

Commit 3acc7f63 authored by Chris Manton's avatar Chris Manton Committed by Automerger Merge Worker
Browse files

Dump SDP control blocks when initiator resource limit reached am: 81312f12

parents 085dfb24 81312f12
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2360,6 +2360,7 @@ cc_test {
        ":TestMockStackBtm",
        ":TestMockStackL2cap",
        ":TestMockStackMetrics",
        "test/sdp/stack_sdp_api_test.cc",
        "test/sdp/stack_sdp_db_test.cc",
        "test/sdp/stack_sdp_parse_test.cc",
        "test/sdp/stack_sdp_test.cc",
+22 −21
Original line number Diff line number Diff line
@@ -31,12 +31,12 @@
#include <string.h>

#include <cstdint>
#include <utility>

#include "internal_include/bt_target.h"
#include "main/shim/dumpsys.h"
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/sdp_api.h"
#include "stack/include/sdpdefs.h"
#include "stack/sdp/internal/sdp_api.h"
#include "stack/sdp/sdpint.h"
@@ -86,7 +86,7 @@ bool SDP_InitDiscoveryDb(tSDP_DISCOVERY_DB* p_db, uint32_t len, uint16_t num_uui
    return false;
  }

  memset(p_db, 0, (size_t)len);
  memset(p_db, 0, static_cast<size_t>(len));

  p_db->mem_size = len - sizeof(tSDP_DISCOVERY_DB);
  p_db->mem_free = p_db->mem_size;
@@ -145,6 +145,8 @@ bool SDP_ServiceSearchRequest(const RawAddress& bd_addr, tSDP_DISCOVERY_DB* p_db
  /* Specific BD address */
  tCONN_CB* p_ccb = sdp_conn_originate(bd_addr);
  if (!p_ccb) {
    log::warn("no spare CCB for peer:{} max:{}", bd_addr, kMaxSdpConnections);
    sdpu_dump_all_ccb();
    return false;
  }

@@ -174,6 +176,8 @@ bool SDP_ServiceSearchAttributeRequest(const RawAddress& bd_addr, tSDP_DISCOVERY
  /* Specific BD address */
  tCONN_CB* p_ccb = sdp_conn_originate(bd_addr);
  if (!p_ccb) {
    log::warn("no spare CCB for peer:{} max:{}", bd_addr, kMaxSdpConnections);
    sdpu_dump_all_ccb();
    return false;
  }

@@ -205,6 +209,8 @@ bool SDP_ServiceSearchAttributeRequest2(
  /* Specific BD address */
  tCONN_CB* p_ccb = sdp_conn_originate(bd_addr);
  if (!p_ccb) {
    log::warn("no spare CCB for peer:{} max:{}", bd_addr, kMaxSdpConnections);
    sdpu_dump_all_ccb();
    return false;
  }

@@ -275,13 +281,11 @@ bool SDP_FindServiceUUIDInRec(const tSDP_DISC_REC* p_rec, Uuid* p_uuid) {
          }

          return true;
        }

        } else {
          /* Checking for Toyota G Block Car Kit:
           **  This car kit puts an extra data element sequence
           **  where the UUID is suppose to be!!!
           */
        else {
          if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) {
            /* Look through data element sequence until no more UUIDs */
            for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr;
@@ -404,17 +408,14 @@ tSDP_DISC_REC* SDP_FindServiceInDb(const tSDP_DISCOVERY_DB* p_db, uint16_t servi

          if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE &&
              (service_uuid == 0 || (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 2 &&
                                     p_sattr->attr_value.v.u16 == service_uuid)))
                                     p_sattr->attr_value.v.u16 == service_uuid))) {
            /* for a specific uuid, or any one */
          {
            return p_rec;
          }

          } else {
            /* Checking for Toyota G Block Car Kit:
             **  This car kit puts an extra data element sequence
             **  where the UUID is suppose to be!!!
             */
          else {
            if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE) {
              /* Look through data element sequence until no more UUIDs */
              for (p_extra_sattr = p_sattr->attr_value.v.p_sub_attr; p_extra_sattr;
@@ -705,8 +706,8 @@ bool SDP_FindProfileVersionInRec(const tSDP_DISC_REC* p_rec, uint16_t profile_uu

              return true;
            } else {
              return false; /* The type and/or size was not valid for the
                               profile list version */
              return false;  // The type and/or size was not valid for the
                             //   profile list version
            }
          }
        }
+3 −3
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ static void sdp_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid, uint1
                            uint8_t /* l2cap_id */) {
  tCONN_CB* p_ccb = sdpu_allocate_ccb();
  if (p_ccb == NULL) {
    log::warn("no spare CCB for peer:{} cid:{}", bd_addr, l2cap_cid);
    log::warn("no spare CCB for peer:{} max:{} cid:{}", bd_addr,
              static_cast<size_t>(SDP_MAX_CONNECTIONS), l2cap_cid);
    sdpu_dump_all_ccb();
    return;
  }
@@ -268,7 +269,6 @@ tCONN_CB* sdp_conn_originate(const RawAddress& bd_addr) {
  /* Allocate a new CCB. Return if none available. */
  tCONN_CB* p_ccb = sdpu_allocate_ccb();
  if (p_ccb == NULL) {
    log::warn("no spare CCB for peer {}", bd_addr);
    return NULL;
  }

@@ -376,7 +376,7 @@ static void sdp_disconnect_cfm(uint16_t l2cap_cid, uint16_t /* result */) {
 *
 ******************************************************************************/
void sdp_conn_timer_timeout(void* data) {
  tCONN_CB& ccb = *(tCONN_CB*)data;
  tCONN_CB& ccb = *(static_cast<tCONN_CB*>(data));

  log::verbose("SDP - CCB timeout in state: {}  CID: 0x{:x}", sdp_state_text(ccb.con_state),
               ccb.connection_id);
+1 −1
Original line number Diff line number Diff line
@@ -244,7 +244,7 @@ void sdp_disconnect(tCONN_CB* p_ccb, tSDP_REASON reason);

void sdp_conn_timer_timeout(void* data);

tCONN_CB* sdp_conn_originate(const RawAddress& bd_addr);
[[nodiscard]] tCONN_CB* sdp_conn_originate(const RawAddress& bd_addr);

/* Functions provided by sdp_utils.cc
 */
+130 −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.
 */

#include <gtest/gtest.h>
#include <stdlib.h>

#include <cstddef>
#include <cstdint>
#include <memory>

#include "btif/include/btif_common.h"
#include "osi/include/allocator.h"
#include "stack/include/sdp_api.h"
#include "stack/sdp/sdpint.h"
#include "test/fake/fake_osi.h"
#include "test/mock/mock_osi_allocator.h"
#include "test/mock/mock_stack_l2cap_api.h"

#ifndef BT_DEFAULT_BUFFER_SIZE
#define BT_DEFAULT_BUFFER_SIZE (4096 + 16)
#endif

namespace {
constexpr uint8_t kSDP_MAX_CONNECTIONS = static_cast<uint8_t>(SDP_MAX_CONNECTIONS);

const RawAddress kRawAddress = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
int L2CA_ConnectReqWithSecurity_cid = 0x42;
tSDP_DISCOVERY_DB* sdp_db = nullptr;

class StackSdpWithMocksTest : public ::testing::Test {
protected:
  void SetUp() override {
    fake_osi_ = std::make_unique<::test::fake::FakeOsi>();

    test::mock::stack_l2cap_api::L2CA_ConnectReqWithSecurity.body =
            [](uint16_t /* psm */, const RawAddress& /* p_bd_addr */, uint16_t /* sec_level */) {
              return ++L2CA_ConnectReqWithSecurity_cid;
            };
    test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */,
                                                          BT_HDR* p_data) -> tL2CAP_DW_RESULT {
      osi_free_and_reset(reinterpret_cast<void**>(&p_data));
      return tL2CAP_DW_RESULT::FAILED;
    };
    test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; };
    test::mock::stack_l2cap_api::L2CA_RegisterWithSecurity.body =
            [](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 */) { return psm; };
  }

  void TearDown() override {
    test::mock::stack_l2cap_api::L2CA_ConnectReqWithSecurity = {};
    test::mock::stack_l2cap_api::L2CA_RegisterWithSecurity = {};
    test::mock::stack_l2cap_api::L2CA_DataWrite = {};
    test::mock::stack_l2cap_api::L2CA_DisconnectReq = {};

    fake_osi_.reset();
  }

  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
};

class StackSdpApiTest : public StackSdpWithMocksTest {
protected:
  void SetUp() override {
    StackSdpWithMocksTest::SetUp();
    sdp_init();
    sdp_db = static_cast<tSDP_DISCOVERY_DB*>(osi_malloc(BT_DEFAULT_BUFFER_SIZE));
  }

  void TearDown() override {
    osi_free(sdp_db);
    sdp_free();
    StackSdpWithMocksTest::TearDown();
  }
};

}  // namespace

TEST_F(StackSdpApiTest, nop) {}

TEST_F(StackSdpApiTest, SDP_ServiceSearchRequest) {
  tSDP_DISCOVERY_DB db;
  for (uint8_t i = 0; i < kSDP_MAX_CONNECTIONS; i++) {
    RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, i});
    ASSERT_NE(nullptr, sdp_conn_originate(bd_addr));
  }
  ASSERT_FALSE(bluetooth::legacy::stack::sdp::get_legacy_stack_sdp_api()
                       ->service.SDP_ServiceSearchRequest(
                               kRawAddress, &db,
                               [](const RawAddress& /* bd_addr */, tSDP_RESULT /* result */) {}));
}

TEST_F(StackSdpApiTest, SDP_ServiceSearchAttributeRequest) {
  tSDP_DISCOVERY_DB db;
  for (uint8_t i = 0; i < kSDP_MAX_CONNECTIONS; i++) {
    RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, i});
    ASSERT_NE(nullptr, sdp_conn_originate(bd_addr));
  }
  ASSERT_FALSE(bluetooth::legacy::stack::sdp::get_legacy_stack_sdp_api()
                       ->service.SDP_ServiceSearchAttributeRequest(
                               kRawAddress, &db,
                               [](const RawAddress& /* bd_addr */, tSDP_RESULT /* result */) {}));
}

TEST_F(StackSdpApiTest, SDP_ServiceSearchAttributeRequest2) {
  tSDP_DISCOVERY_DB db;
  for (uint8_t i = 0; i < kSDP_MAX_CONNECTIONS; i++) {
    RawAddress bd_addr = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, i});
    ASSERT_NE(nullptr, sdp_conn_originate(bd_addr));
  }
  ASSERT_FALSE(bluetooth::legacy::stack::sdp::get_legacy_stack_sdp_api()
                       ->service.SDP_ServiceSearchAttributeRequest2(
                               kRawAddress, &db,
                               base::BindRepeating([](const RawAddress& /* bd_addr */,
                                                      tSDP_RESULT /* result */) {})));
}