blob: 5747cc89b198a9b708a72d2830886e3ea63a0e44 [file] [log] [blame]
// Copyright 2020 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/public/pw_bluetooth_sapphire/internal/host/common/supplement_data.h"
#include <gtest/gtest.h>
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
namespace bt {
namespace {
TEST(SupplementDataTest, ReaderEmptyData) {
BufferView empty;
SupplementDataReader reader(empty);
EXPECT_FALSE(reader.is_valid());
EXPECT_FALSE(reader.HasMoreData());
}
TEST(SupplementDataTest, ReaderMalformedData) {
// TLV length exceeds the size of the payload
StaticByteBuffer bytes0(0x01);
SupplementDataReader reader(bytes0);
EXPECT_FALSE(reader.is_valid());
EXPECT_FALSE(reader.HasMoreData());
StaticByteBuffer bytes(0x05, 0x00, 0x00, 0x00, 0x00);
reader = SupplementDataReader(bytes);
EXPECT_FALSE(reader.is_valid());
EXPECT_FALSE(reader.HasMoreData());
// TLV length is 0. This is not considered malformed. Data should be valid but
// should not return more data.
bytes = StaticByteBuffer(0x00, 0x00, 0x00, 0x00, 0x00);
reader = SupplementDataReader(bytes);
EXPECT_TRUE(reader.is_valid());
EXPECT_FALSE(reader.HasMoreData());
// First field is valid, second field is not.
DataType type;
BufferView data;
bytes = StaticByteBuffer(0x02, 0x00, 0x00, 0x02, 0x00);
reader = SupplementDataReader(bytes);
EXPECT_FALSE(reader.is_valid());
EXPECT_FALSE(reader.HasMoreData());
EXPECT_FALSE(reader.GetNextField(&type, &data));
// First field is valid, second field has length 0.
bytes = StaticByteBuffer(0x02, 0x00, 0x00, 0x00, 0x00);
reader = SupplementDataReader(bytes);
EXPECT_TRUE(reader.is_valid());
EXPECT_TRUE(reader.HasMoreData());
EXPECT_TRUE(reader.GetNextField(&type, &data));
EXPECT_FALSE(reader.HasMoreData());
EXPECT_FALSE(reader.GetNextField(&type, &data));
}
TEST(SupplementDataTest, ReaderParseFields) {
StaticByteBuffer bytes(0x02, 0x01, 0x00, 0x05, 0x09, 'T', 'e', 's', 't');
SupplementDataReader reader(bytes);
EXPECT_TRUE(reader.is_valid());
EXPECT_TRUE(reader.HasMoreData());
DataType type;
BufferView data;
EXPECT_TRUE(reader.GetNextField(&type, &data));
EXPECT_EQ(DataType::kFlags, type);
EXPECT_EQ(1u, data.size());
EXPECT_TRUE(ContainersEqual(StaticByteBuffer(0x00), data));
EXPECT_TRUE(reader.HasMoreData());
EXPECT_TRUE(reader.GetNextField(&type, &data));
EXPECT_EQ(DataType::kCompleteLocalName, type);
EXPECT_EQ(4u, data.size());
EXPECT_TRUE(ContainersEqual(std::string("Test"), data));
EXPECT_FALSE(reader.HasMoreData());
EXPECT_FALSE(reader.GetNextField(&type, &data));
}
// Helper for computing the size of a string literal at compile time. sizeof()
// would have worked too but that counts the null character.
template <std::size_t N>
constexpr size_t StringSize(char const (&str)[N]) {
return N - 1;
}
TEST(SupplementDataTest, WriteFieldAndVerifyContents) {
constexpr char kValue0[] = "value zero";
constexpr char kValue1[] = "value one";
constexpr char kValue2[] = "value two";
constexpr char kValue3[] = "value three";
// Have just enough space for the first three values (+ 6 for 2 extra octets
// for each TLV field).
constexpr char kBufferSize =
StringSize(kValue0) + StringSize(kValue1) + StringSize(kValue2) + 6;
StaticByteBuffer<kBufferSize> buffer;
SupplementDataWriter writer(&buffer);
EXPECT_EQ(0u, writer.bytes_written());
// We write malformed values here for testing purposes.
EXPECT_TRUE(writer.WriteField(DataType::kFlags, BufferView(kValue0)));
EXPECT_EQ(StringSize(kValue0) + 2, writer.bytes_written());
EXPECT_TRUE(
writer.WriteField(DataType::kShortenedLocalName, BufferView(kValue1)));
EXPECT_EQ(StringSize(kValue0) + 2 + StringSize(kValue1) + 2,
writer.bytes_written());
// Trying to write kValue3 should fail because there isn't enough room left in
// the buffer.
EXPECT_FALSE(
writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));
// Writing kValue2 should fill up the buffer.
EXPECT_TRUE(
writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue2)));
EXPECT_FALSE(
writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));
EXPECT_EQ(buffer.size(), writer.bytes_written());
// Verify the contents.
DataType type;
BufferView value;
SupplementDataReader reader(buffer);
EXPECT_TRUE(reader.is_valid());
EXPECT_TRUE(reader.GetNextField(&type, &value));
EXPECT_EQ(DataType::kFlags, type);
EXPECT_EQ(kValue0, value.AsString());
EXPECT_TRUE(reader.GetNextField(&type, &value));
EXPECT_EQ(DataType::kShortenedLocalName, type);
EXPECT_EQ(kValue1, value.AsString());
EXPECT_TRUE(reader.GetNextField(&type, &value));
EXPECT_EQ(DataType::kCompleteLocalName, type);
EXPECT_EQ(kValue2, value.AsString());
EXPECT_FALSE(reader.GetNextField(&type, &value));
}
} // namespace
} // namespace bt