blob: a864b24f0e7062164a94cb74198b7af88d2005f8 [file] [log] [blame]
// 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.
#ifndef GARNET_DRIVERS_BLUETOOTH_LIB_GATT_SERVER_H_
#define GARNET_DRIVERS_BLUETOOTH_LIB_GATT_SERVER_H_
#include "garnet/drivers/bluetooth/lib/att/bearer.h"
#include "garnet/drivers/bluetooth/lib/common/uuid.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"
namespace btlib {
namespace att {
class Attribute;
class Database;
class PacketReader;
} // namespace att
namespace gatt {
// A GATT Server implements the server-role of the ATT protocol over a single
// ATT Bearer. A unique Server instance should exist for each logical link that
// supports GATT.
//
// A Server responds to incoming requests by querying the database that it
// is initialized with. Each Server shares an att::Bearer with a Client.
class Server final {
public:
// |peer_id| is the 128-bit UUID that identifies the peer device.
// |database| will be queried by the Server to resolve transactions.
// |bearer| is the ATT data bearer that this Server operates on.
Server(const std::string& peer_id,
fxl::RefPtr<att::Database> database,
fxl::RefPtr<att::Bearer> bearer);
~Server();
// Sends a Handle-Value notification or indication PDU with the given
// attribute handle. If |indicate| is true, then an indication will be sent.
// The underlying att::Bearer will disconnect the link if a confirmation is
// not received in a timely manner.
void SendNotification(att::Handle handle,
const common::ByteBuffer& value,
bool indicate);
private:
// ATT protocol request handlers:
void OnExchangeMTU(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnFindInformation(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnReadByGroupType(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnReadByType(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnReadRequest(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnWriteRequest(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnWriteCommand(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnReadBlobRequest(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
void OnFindByTypeValueRequest(att::Bearer::TransactionId tid,
const att::PacketReader& packet);
// Helper function to serve the Read By Type and Read By Group Type requests.
// This searches |db| for attributes with the given |type| and adds as many
// attributes as it can fit within the given |max_data_list_size|. The
// attribute value that should be included within each attribute data list
// entry is returned in |out_value_size|.
//
// If the result is a dynamic attribute, |out_results| will contain at most
// one entry. |out_value_size| will point to an undefined value in that case.
//
// Returns att::ErrorCode::kNoError on success. On error, returns an error
// code that can be used in a ATT Error Response.
att::ErrorCode ReadByTypeHelper(
att::Handle start,
att::Handle end,
const common::UUID& type,
bool group_type,
size_t max_data_list_size,
size_t max_value_size,
size_t entry_prefix_size,
size_t* out_value_size,
std::list<const att::Attribute*>* out_results);
std::string peer_id_;
fxl::RefPtr<att::Database> db_;
fxl::RefPtr<att::Bearer> att_;
// ATT protocol request handler IDs
att::Bearer::HandlerId exchange_mtu_id_;
att::Bearer::HandlerId find_information_id_;
att::Bearer::HandlerId read_by_group_type_id_;
att::Bearer::HandlerId read_by_type_id_;
att::Bearer::HandlerId read_req_id_;
att::Bearer::HandlerId write_req_id_;
att::Bearer::HandlerId write_cmd_id_;
att::Bearer::HandlerId read_blob_req_id_;
att::Bearer::HandlerId find_by_type_value_;
fxl::WeakPtrFactory<Server> weak_ptr_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(Server);
};
} // namespace gatt
} // namespace btlib
#endif // GARNET_DRIVERS_BLUETOOTH_LIB_GATT_SERVER_H_