| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/connectivity/bluetooth/core/bt-host/hci/advertising_report_parser.h" |
| |
| #include "gtest/gtest.h" |
| |
| #include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h" |
| #include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h" |
| #include "src/connectivity/bluetooth/core/bt-host/hci/control_packets.h" |
| |
| namespace bt { |
| namespace hci { |
| namespace test { |
| namespace { |
| |
| TEST(HCI_AdvertisingReportParserTest, EmptyReport) { |
| auto bytes = common::CreateStaticByteBuffer(0x3E, 0x02, 0x02, 0x00); |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_FALSE(parser.HasMoreReports()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, SingleReportMalformed) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x0B, 0x02, 0x01, // HCI event header and LE Meta Event params |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00 // |length_data|. RSSI is missing |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.encountered_error()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_TRUE(parser.encountered_error()); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, SingleReportNoData) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x0C, 0x02, 0x01, // HCI event header and LE Meta Event params |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00, 0x7F // |length_data|, RSSI |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type); |
| EXPECT_EQ("06:05:04:03:02:01", data->address.ToString()); |
| EXPECT_EQ(0u, data->length_data); |
| EXPECT_EQ(kRSSIInvalid, rssi); |
| |
| // No other reports |
| EXPECT_FALSE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| |
| EXPECT_FALSE(parser.encountered_error()); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, ReportsValidInvalid) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x16, 0x02, 0x02, // HCI event header and LE Meta Event params |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00, 0x7F, // |length_data|, RSSI |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x0A, 0x7F // malformed |length_data|, RSSI |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.encountered_error()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type); |
| EXPECT_EQ("06:05:04:03:02:01", data->address.ToString()); |
| EXPECT_EQ(0u, data->length_data); |
| EXPECT_EQ(kRSSIInvalid, rssi); |
| |
| // There are more reports... |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.encountered_error()); |
| |
| // ...but the report is malformed. |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_TRUE(parser.encountered_error()); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, ReportsAllValid) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x28, 0x02, 0x03, // HCI event header and LE Meta Event params |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00, 0x7F, // |length_data|, RSSI |
| |
| 0x00, 0x01, // event_type, address_type |
| 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // address |
| 0x03, 0x01, 0x02, 0x03, 0x0F, // |length_data|, data, RSSI |
| |
| 0x01, 0x00, // event_type, address_type |
| 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, // address |
| 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // |length_data|, data |
| 0x01 // RSSI |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type); |
| EXPECT_EQ("06:05:04:03:02:01", data->address.ToString()); |
| EXPECT_EQ(0u, data->length_data); |
| EXPECT_EQ(kRSSIInvalid, rssi); |
| |
| // There are more reports |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kRandom, data->address_type); |
| EXPECT_EQ("0C:0B:0A:09:08:07", data->address.ToString()); |
| EXPECT_EQ(3, data->length_data); |
| EXPECT_TRUE( |
| common::ContainersEqual(std::array<uint8_t, 3>{{0x01, 0x02, 0x03}}, |
| data->data, data->length_data)); |
| EXPECT_EQ(15, rssi); |
| |
| // There are more reports |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvDirectInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublic, data->address_type); |
| EXPECT_EQ("12:11:10:0F:0E:0D", data->address.ToString()); |
| EXPECT_EQ(5, data->length_data); |
| EXPECT_TRUE(common::ContainersEqual( |
| std::array<uint8_t, 5>{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}, data->data, |
| data->length_data)); |
| EXPECT_EQ(1, rssi); |
| |
| // No more reports. |
| EXPECT_FALSE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| |
| EXPECT_FALSE(parser.encountered_error()); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, ReportCountLessThanPayloadSize) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x28, 0x02, // HCI event header and LE Meta Event param |
| 0x01, // Event count is 1, even though packet contains 3 |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00, 0x7F, // |length_data|, RSSI |
| |
| 0x00, 0x01, // event_type, address_type |
| 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // address |
| 0x03, 0x01, 0x02, 0x03, 0x0F, // |length_data|, data, RSSI |
| |
| 0x01, 0x00, // event_type, address_type |
| 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, // address |
| 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // |length_data|, data |
| 0x01 // RSSI |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.encountered_error()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type); |
| EXPECT_EQ("06:05:04:03:02:01", data->address.ToString()); |
| EXPECT_EQ(0u, data->length_data); |
| EXPECT_EQ(kRSSIInvalid, rssi); |
| |
| // Since the packet is malformed (the event payload contains 3 reports while |
| // the header states there is only 1) this should return false. |
| EXPECT_FALSE(parser.encountered_error()); |
| EXPECT_FALSE(parser.HasMoreReports()); |
| EXPECT_TRUE(parser.encountered_error()); |
| |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_TRUE(parser.encountered_error()); |
| } |
| |
| TEST(HCI_AdvertisingReportParserTest, ReportCountGreaterThanPayloadSize) { |
| // clang-format off |
| |
| auto bytes = common::CreateStaticByteBuffer( |
| 0x3E, 0x0C, 0x02, // HCI event header and LE Meta Event param |
| 0x02, // Event count is 2, even though packet contains 1 |
| 0x03, 0x02, // event_type, address_type |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address |
| 0x00, 0x7F // |length_data|, RSSI |
| ); |
| |
| // clang-format on |
| |
| auto event = EventPacket::New(bytes.size() - sizeof(EventHeader)); |
| event->mutable_view()->mutable_data().Write(bytes); |
| event->InitializeFromBuffer(); |
| |
| AdvertisingReportParser parser(*event); |
| EXPECT_TRUE(parser.HasMoreReports()); |
| |
| const LEAdvertisingReportData* data; |
| int8_t rssi; |
| EXPECT_TRUE(parser.GetNextReport(&data, &rssi)); |
| EXPECT_EQ(LEAdvertisingEventType::kAdvNonConnInd, data->event_type); |
| EXPECT_EQ(LEAddressType::kPublicIdentity, data->address_type); |
| EXPECT_EQ("06:05:04:03:02:01", data->address.ToString()); |
| EXPECT_EQ(0u, data->length_data); |
| EXPECT_EQ(kRSSIInvalid, rssi); |
| |
| EXPECT_FALSE(parser.encountered_error()); |
| |
| // Since the packet is malformed (the event payload contains 1 report while |
| // the header states there are 2) this should return false. |
| EXPECT_FALSE(parser.HasMoreReports()); |
| EXPECT_FALSE(parser.GetNextReport(&data, &rssi)); |
| |
| EXPECT_TRUE(parser.encountered_error()); |
| } |
| |
| } // namespace |
| } // namespace test |
| } // namespace hci |
| } // namespace bt |