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

Commit 394712b1 authored by Aritra Sen's avatar Aritra Sen Committed by Gerrit Code Review
Browse files

Merge "Correct SCN allocation within bounds. Ensure Allocate SCN returns a...

Merge "Correct SCN allocation within bounds. Ensure Allocate SCN returns a value in [1, PORT_MAX_RFC_PORTS) or 0 if no port available." into main
parents 3fea1e9a a59b27de
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -125,10 +125,10 @@ cc_library_static {
        "bnep/bnep_api.cc",
        "bnep/bnep_main.cc",
        "bnep/bnep_utils.cc",
        "btm/hfp_msbc_decoder.cc",
        "btm/hfp_msbc_encoder.cc",
        "btm/hfp_lc3_decoder.cc",
        "btm/hfp_lc3_encoder.cc",
        "btm/hfp_msbc_decoder.cc",
        "btm/hfp_msbc_encoder.cc",
        "hid/hidd_api.cc",
        "hid/hidd_conn.cc",
        "hid/hidh_api.cc",
@@ -1409,16 +1409,17 @@ cc_test {
        "btm/btm_sco_hci.cc",
        "btm/btm_sco_hfp_hal.cc",
        "btm/btm_sec.cc",
        "btm/hfp_msbc_decoder.cc",
        "btm/hfp_msbc_encoder.cc",
        "btm/hfp_lc3_decoder.cc",
        "btm/hfp_lc3_encoder.cc",
        "btm/hfp_msbc_decoder.cc",
        "btm/hfp_msbc_encoder.cc",
        "metrics/stack_metrics_logging.cc",
        "test/btm/btm_scn_test.cc",
        "test/btm/peer_packet_types_test.cc",
        "test/btm/sco_hci_test.cc",
        "test/btm/sco_pkt_status_test.cc",
        "test/btm/stack_btm_regression_tests.cc",
        "test/btm/stack_btm_test.cc",
        "test/btm/sco_pkt_status_test.cc",
        "test/common/mock_eatt.cc",
        "test/stack_include_test.cc",
    ],
+10 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#ifndef BTM_INT_TYPES_H
#define BTM_INT_TYPES_H

#include <gtest/gtest_prod.h>

#include <cstdint>
#include <memory>
#include <string>
@@ -396,6 +398,14 @@ typedef struct tBTM_CB {
  friend bool BTM_FreeSCN(uint8_t scn);
  uint8_t btm_scn[BTM_MAX_SCN_];
  uint8_t btm_available_index;

  // give access to private method for test:
  friend class BtmAllocateSCNTest;
  FRIEND_TEST(BtmAllocateSCNTest, can_allocate_all_scns);
  FRIEND_TEST(BtmAllocateSCNTest, only_last_scn_available);
  FRIEND_TEST(BtmAllocateSCNTest, scn_available_after_available_index);
  FRIEND_TEST(BtmAllocateSCNTest, scn_available_before_available_index);
  FRIEND_TEST(BtmAllocateSCNTest, no_scn_available);
} tBTM_CB;

/* security action for L2CAP COC channels */
+8 −5
Original line number Diff line number Diff line
@@ -34,8 +34,11 @@ extern tBTM_CB btm_cb;
uint8_t BTM_AllocateSCN(void) {
  BTM_TRACE_DEBUG("BTM_AllocateSCN");

  // stack reserves scn 1 for HFP, HSP we still do the correct way
  for (uint8_t x = btm_cb.btm_available_index; x < PORT_MAX_RFC_PORTS; x++) {
  // stack reserves scn 1 for HFP, HSP we still do the correct way.
  // SCN can be allocated in the range of [1, PORT_MAX_RFC_PORTS). Since (x + 1)
  // is returned, we iterate to less than PORT_MAX_RFC_PORTS - 1.
  for (uint8_t x = btm_cb.btm_available_index; x < PORT_MAX_RFC_PORTS - 1;
       x++) {
    if (!btm_cb.btm_scn[x]) {
      btm_cb.btm_scn[x] = true;
      btm_cb.btm_available_index = (x + 1);
@@ -43,10 +46,10 @@ uint8_t BTM_AllocateSCN(void) {
    }
  }

  // In order to avoid OOB, btm_available_index must be less than or equal to
  // PORT_MAX_RFC_PORTS
  // In order to avoid OOB, btm_available_index must be less than
  // PORT_MAX_RFC_PORTS.
  btm_cb.btm_available_index =
      std::min(btm_cb.btm_available_index, (uint8_t)PORT_MAX_RFC_PORTS);
      std::min(btm_cb.btm_available_index, (uint8_t)(PORT_MAX_RFC_PORTS - 1));

  // If there's no empty SCN from _last_index to BTM_MAX_SCN.
  for (uint8_t y = 1; y < btm_cb.btm_available_index; y++) {
+1 −1
Original line number Diff line number Diff line
@@ -18,6 +18,6 @@

#include <cstdint>

uint8_t BTM_AllocateSCN(void);
bool BTM_FreeSCN(uint8_t scn);
bool BTM_TryAllocateSCN(uint8_t scn);
bool BTM_TryAllocateSCN(uint8_t scn);
+91 −0
Original line number Diff line number Diff line
/*
 *
 *  Copyright 2023 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 "stack/btm/btm_scn.h"

#include <gtest/gtest.h>

#include "stack/btm/btm_int_types.h"  // tBTM_CB
#include "stack/include/rfcdefs.h"    // PORT_MAX_RFC_PORTS

extern tBTM_CB btm_cb;

using testing::Test;

class BtmAllocateSCNTest : public Test {
 public:
 protected:
  void SetUp() override {
    btm_cb.btm_available_index = 1;
    for (int i = 0; i < PORT_MAX_RFC_PORTS; i++) {
      btm_cb.btm_scn[i] = false;
    }
  }

  void TearDown() override {}
};

TEST_F(BtmAllocateSCNTest, scn_available_after_available_index) {
  btm_cb.btm_available_index = 5;
  uint8_t occupied_idx[] = {1, 2, 3, 4, 5, 6, 7};
  for (uint8_t idx : occupied_idx) {
    btm_cb.btm_scn[idx] = true;
  }

  uint8_t scn = BTM_AllocateSCN();
  ASSERT_EQ(scn, 9);  // All indexes up to 7 are occupied; hence index 8 i.e.
                      // scn 9 should return
}

TEST_F(BtmAllocateSCNTest, scn_available_before_available_index) {
  btm_cb.btm_available_index = 28;
  uint8_t occupied_idx[] = {26, 27, 28, 29};
  for (uint8_t idx : occupied_idx) {
    btm_cb.btm_scn[idx] = true;
  }

  uint8_t scn = BTM_AllocateSCN();
  ASSERT_EQ(scn, 2);  // All SCN from available to 30 are occupied; hence cycle
                      // to beginning.
}

TEST_F(BtmAllocateSCNTest, can_allocate_all_scns) {
  for (uint8_t scn = 2; scn < PORT_MAX_RFC_PORTS; scn++) {
    EXPECT_EQ(BTM_AllocateSCN(), scn);
  }
}

TEST_F(BtmAllocateSCNTest, only_last_scn_available) {
  // Fill all relevants SCN except the last
  for (uint8_t scn = 2; scn < PORT_MAX_RFC_PORTS - 1; scn++) {
    btm_cb.btm_scn[scn - 1] = true;
  }

  EXPECT_EQ(BTM_AllocateSCN(), PORT_MAX_RFC_PORTS - 1);
}

TEST_F(BtmAllocateSCNTest, no_scn_available) {
  btm_cb.btm_available_index = 2;
  for (int i = 1; i < PORT_MAX_RFC_PORTS - 1;
       i++) {  // Fill all relevants SCN indexes (1 to 29)
    btm_cb.btm_scn[i] = true;
  }

  uint8_t scn = BTM_AllocateSCN();
  EXPECT_EQ(scn, 0) << "scn = " << scn << "and not 0";
}
 No newline at end of file