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

Commit f564ce4e authored by Chris Manton's avatar Chris Manton
Browse files

Introduce stack_hci_test

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

Change-Id: Ib8e78e49a1f4e4f48e811eac0342e9d33eb7ceb4
parent 19ea934c
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -766,3 +766,45 @@ cc_test {
        },
    },
}

cc_test {
    name: "net_test_stack_hci",
    test_suites: ["device-tests"],
    host_supported: true,
    defaults: ["fluoride_defaults"],
    local_include_dirs: [
        "include",
        "btm",
        "test/common",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/vnd/ble",
    ],
    srcs: crypto_toolbox_srcs + [
        "test/hci/stack_hci_test.cc",
    ],
    static_libs: [
        "libbt-common",
        "libbt-protos-lite",
        "libbte",
        "libgmock",
        "liblog",
        "libosi",
        "libbtdevice",
    ],
    shared_libs: [
        "libprotobuf-cpp-lite",
        "libcrypto",
    ],
    sanitize: {
        address: true,
        all_undefined: true,
        cfi: true,
        integer_overflow: true,
        scs: true,
        diag: {
            undefined : true
        },
    },
}
+34 −1
Original line number Diff line number Diff line
@@ -860,7 +860,40 @@ typedef enum : uint8_t {
*/
#define HCIE_PREAMBLE_SIZE 2
#define HCI_SCO_PREAMBLE_SIZE 3
#define HCI_DATA_PREAMBLE_SIZE 4

// Packet boundary flags
constexpr uint8_t kFIRST_NON_AUTOMATICALLY_FLUSHABLE = 0x0;
constexpr uint8_t kCONTINUING_FRAGMENT = 0x1;
constexpr uint8_t kHCI_FIRST_AUTOMATICALLY_FLUSHABLE = 0x2;

struct HciDataPreambleBits {
  uint16_t handle : 12;
  uint16_t boundary : 2;
  uint16_t broadcast : 1;
  uint16_t unused15 : 1;
  uint16_t length;
};
struct HciDataPreambleRaw {
  uint16_t word0;
  uint16_t word1;
};
union HciDataPreamble {
  HciDataPreambleBits bits;
  HciDataPreambleRaw raw;
  void Serialize(uint8_t* data) {
    *data++ = ((raw.word0) & 0xff);
    *data++ = (((raw.word0) >> 8) & 0xff);
    *data++ = ((raw.word1) & 0xff);
    *data++ = (((raw.word1 >> 8)) & 0xff);
  }
  bool IsFlushable() const {
    return bits.boundary == kHCI_FIRST_AUTOMATICALLY_FLUSHABLE;
  }
  void SetFlushable() { bits.boundary = kHCI_FIRST_AUTOMATICALLY_FLUSHABLE; }
};
#define HCI_DATA_PREAMBLE_SIZE sizeof(HciDataPreamble)
static_assert(HCI_DATA_PREAMBLE_SIZE == 4);
static_assert(sizeof(HciDataPreambleRaw) == sizeof(HciDataPreambleBits));

/* local Bluetooth controller id for AMP HCI */
#define LOCAL_BR_EDR_CONTROLLER_ID 0
+133 −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 "osi/include/log.h"
#include "stack/include/hcidefs.h"
#include "stack/include/l2cdefs.h"
#include "test/mock/mock_hcic_hcicmds.h"

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

namespace mock = test::mock::hcic_hcicmds;

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 StackHciTest : public Test {
 public:
 protected:
  void SetUp() override { mock_function_count_map.clear(); }
  void TearDown() override {}
};

TEST_F(StackHciTest, hci_preamble) {
  {
    HciDataPreamble preamble;

    ASSERT_EQ(sizeof(preamble), HCI_DATA_PREAMBLE_SIZE);

    preamble.bits.handle = 0xfff;
    preamble.bits.boundary = 0x3;
    preamble.bits.broadcast = 0x1;
    preamble.bits.unused15 = 0x0;
    preamble.bits.length = 0xffff;

    ASSERT_EQ(0x7fff, preamble.raw.word0);
    ASSERT_EQ(0xffff, preamble.raw.word1);

    const uint8_t exp[] = {0xff, 0x7f, 0xff, 0xff};
    uint8_t act[sizeof(preamble)];
    preamble.Serialize(act);
    ASSERT_EQ(0, std::memcmp(exp, act, sizeof(preamble)));
  }

  {
    HciDataPreamble preamble;
    preamble.raw.word0 =
        0x123 | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
    preamble.raw.word1 = 0x4567;

    ASSERT_EQ(sizeof(preamble), HCI_DATA_PREAMBLE_SIZE);

    ASSERT_EQ(0x0123, preamble.raw.word0);
    ASSERT_EQ(0x4567, preamble.raw.word1);

    const uint8_t exp[] = {0x23, 0x01, 0x67, 0x45};
    uint8_t act[sizeof(preamble)];
    preamble.Serialize(act);
    ASSERT_EQ(0, std::memcmp(exp, act, sizeof(preamble)));
  }
  {
    HciDataPreamble preamble;
    preamble.raw.word0 = 0x123 | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
    preamble.raw.word1 = 0x4567;

    ASSERT_EQ(sizeof(preamble), HCI_DATA_PREAMBLE_SIZE);

    ASSERT_EQ(0x2123, preamble.raw.word0);
    ASSERT_EQ(0x4567, preamble.raw.word1);

    const uint8_t exp[] = {0x23, 0x21, 0x67, 0x45};
    uint8_t act[sizeof(preamble)];
    preamble.Serialize(act);
    ASSERT_EQ(0, std::memcmp(exp, act, sizeof(preamble)));
  }

  {
    HciDataPreamble preamble;
    preamble.raw.word0 = 0x0 | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
    preamble.raw.word1 = 0x0;

    ASSERT_EQ(sizeof(preamble), HCI_DATA_PREAMBLE_SIZE);

    ASSERT_EQ(0x2000, preamble.raw.word0);
    ASSERT_EQ(0x0000, preamble.raw.word1);

    const uint8_t exp[] = {0x00, 0x20, 0x00, 0x00};
    uint8_t act[sizeof(preamble)];
    preamble.Serialize(act);
    ASSERT_EQ(0, std::memcmp(exp, act, sizeof(preamble)));
  }

  {
    HciDataPreamble preamble;
    preamble.raw.word0 = 0x0 | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
    preamble.raw.word1 = 0x0;

    ASSERT_TRUE(preamble.IsFlushable());

    preamble.raw.word0 =
        0x0 | (L2CAP_PKT_START << L2CAP_PKT_START_NON_FLUSHABLE);
    ASSERT_TRUE(!preamble.IsFlushable());
  }
}

}  // namespace