From: Chris Manton Date: Fri, 23 Apr 2021 19:54:38 +0000 (-0700) Subject: Introduce stack_hci_test X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8c6b795334;p=android-x86%2Fsystem-bt.git Introduce stack_hci_test Bug: 178752129 Test: gd/cert/run Tag: #refactor BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines Change-Id: Ib8e78e49a1f4e4f48e811eac0342e9d33eb7ceb4 --- diff --git a/stack/Android.bp b/stack/Android.bp index c78c333fe..859649919 100644 --- a/stack/Android.bp +++ b/stack/Android.bp @@ -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: [ + "system/bt", + "system/bt/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 + }, + }, +} diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h index 84e7ebd07..c6a468b30 100644 --- a/stack/include/hcidefs.h +++ b/stack/include/hcidefs.h @@ -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 diff --git a/stack/test/hci/stack_hci_test.cc b/stack/test/hci/stack_hci_test.cc new file mode 100644 index 000000000..8ef98a3df --- /dev/null +++ b/stack/test/hci/stack_hci_test.cc @@ -0,0 +1,133 @@ +/* + * 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 +#include +#include +#include + +#include "osi/include/log.h" +#include "stack/include/hcidefs.h" +#include "stack/include/l2cdefs.h" +#include "test/mock/mock_hcic_hcicmds.h" + +std::map 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