blob: 84542af0e6b0ae55f75c26a93ec055dda5aaa1b8 [file] [log] [blame]
// Copyright 2018 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 "garnet/drivers/bluetooth/lib/sdp/server.h"
#include "gtest/gtest.h"
#include "garnet/drivers/bluetooth/lib/common/test_helpers.h"
#include "garnet/drivers/bluetooth/lib/l2cap/fake_channel_test.h"
namespace btlib {
namespace sdp {
namespace {
using common::LowerBits;
using common::UpperBits;
class SDP_ServerTest : public l2cap::testing::FakeChannelTest {
public:
SDP_ServerTest() = default;
~SDP_ServerTest() = default;
protected:
void SetUp() override { server_ = std::make_unique<Server>(); }
void TearDown() override { server_ = nullptr; }
Server* server() const { return server_.get(); }
private:
std::unique_ptr<Server> server_;
};
constexpr l2cap::ChannelId kSdpChannel = 0x0041;
#define SDP_ERROR_RSP(t_id, code) \
common::CreateStaticByteBuffer(0x01, UpperBits(t_id), LowerBits(t_id), 0x00, \
0x02, UpperBits(uint16_t(code)), \
LowerBits(uint16_t(code)));
// Test:
// - Accepts channels and holds channel open correctly.
// - Packets that are the wrong length are responded to with kInvalidSize
// - Answers with the same TransactionID as sent
TEST_F(SDP_ServerTest, BasicError) {
{
auto fake_chan = CreateFakeChannel(ChannelOptions(kSdpChannel));
EXPECT_TRUE(server()->AddConnection(std::string("one"), fake_chan));
}
EXPECT_TRUE(fake_chan()->activated());
const auto kRspErrSize = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
const auto kTooSmall =
common::CreateStaticByteBuffer(0x01, // SDP_ServiceSearchRequest
0x10, 0x01, // Transaction ID (0x1001)
0x00, 0x09 // Parameter length (9 bytes)
);
const auto kRspTooSmall = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
const auto kTooBig =
common::CreateStaticByteBuffer(0x01, // SDP_ServiceSearchRequest
0x20, 0x10, // Transaction ID (0x2010)
0x00, 0x02, // Parameter length (2 bytes)
0x01, 0x02, 0x03 // 3 bytes of parameters
);
const auto kRspTooBig = SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidSize);
EXPECT_TRUE(ReceiveAndExpect(kTooSmall, kRspTooSmall));
EXPECT_TRUE(ReceiveAndExpect(kTooBig, kRspTooBig));
const auto kRspInvalidSyntax =
SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidRequestSyntax);
// Responses aren't valid requests
EXPECT_TRUE(ReceiveAndExpect(kRspTooBig, kRspInvalidSyntax));
}
// Test:
// - Passes an initialized ServiceRecord that has a matching SericeHandle
// - Doesn't add a service that doesn't contain a ServiceClassIDList
// - Adds a service that is valid.
// - Services can be Unregistered.
TEST_F(SDP_ServerTest, RegisterService) {
EXPECT_FALSE(server()->RegisterService([](auto*) {}));
EXPECT_FALSE(server()->RegisterService([](auto* record) {
record->SetAttribute(kServiceClassIdList, DataElement(uint16_t(42)));
}));
EXPECT_FALSE(server()->RegisterService([](auto* record) {
// kSDPHandle is invalid anyway, but we can't change it.
record->SetAttribute(kServiceRecordHandle, 0);
}));
EXPECT_FALSE(server()->RegisterService(
[](auto* record) { record->RemoveAttribute(kServiceRecordHandle); }));
ServiceHandle handle;
bool added = server()->RegisterService([&handle](ServiceRecord* record) {
EXPECT_TRUE(record);
EXPECT_TRUE(record->HasAttribute(kServiceRecordHandle));
handle = record->handle();
record->SetServiceClassUUIDs({profile::kAVRemoteControl});
});
EXPECT_TRUE(added);
EXPECT_TRUE(server()->UnregisterService(handle));
EXPECT_FALSE(server()->UnregisterService(handle));
}
} // namespace
} // namespace sdp
} // namespace btlib