blob: 696c48b18572ec7f5fe336f61385dafa9e28951c [file] [log] [blame]
// Copyright 2021 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 SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_FIDL_GATT2_REMOTE_SERVICE_SERVER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_FIDL_GATT2_REMOTE_SERVICE_SERVER_H_
#include <fuchsia/bluetooth/gatt2/cpp/fidl.h>
#include "lib/fidl/cpp/binding.h"
#include "src/connectivity/bluetooth/core/bt-host/fidl/server_base.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/macros.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/gatt/gatt.h"
namespace bthost {
class Gatt2RemoteServiceServer : public GattServerBase<fuchsia::bluetooth::gatt2::RemoteService> {
public:
// The maximum number of pending notification values per CharacteristicNotifier (for flow
// control). If exceeded, the notifier protocol is closed.
static const size_t kMaxPendingNotifierValues = 20;
Gatt2RemoteServiceServer(
bt::gatt::RemoteService::WeakPtr service, bt::gatt::GATT::WeakPtr gatt, bt::PeerId peer_id,
fidl::InterfaceRequest<fuchsia::bluetooth::gatt2::RemoteService> request);
~Gatt2RemoteServiceServer() override;
void Close(zx_status_t status);
private:
using NotifierId = uint64_t;
struct CharacteristicNotifier {
bt::gatt::IdType handler_id;
bt::gatt::CharacteristicHandle characteristic_handle;
fidl::InterfacePtr<fuchsia::bluetooth::gatt2::CharacteristicNotifier> notifier;
// For flow control, values are only sent when the client responds to the previous value with an
// acknowledgement. This variable stores the queued values.
std::queue<fuchsia::bluetooth::gatt2::ReadValue> queued_values;
// `last_value_ack` defaults to true so that the first notification queued up is sent to the
// FIDL client immediately.
bool last_value_ack = true;
};
// fuchsia::bluetooth::gatt2::RemoteService overrides:
void DiscoverCharacteristics(DiscoverCharacteristicsCallback callback) override;
void ReadByType(::fuchsia::bluetooth::Uuid uuid, ReadByTypeCallback callback) override;
void ReadCharacteristic(::fuchsia::bluetooth::gatt2::Handle handle,
::fuchsia::bluetooth::gatt2::ReadOptions options,
ReadCharacteristicCallback callback) override;
void WriteCharacteristic(::fuchsia::bluetooth::gatt2::Handle handle, ::std::vector<uint8_t> value,
::fuchsia::bluetooth::gatt2::WriteOptions options,
WriteCharacteristicCallback callback) override;
void ReadDescriptor(::fuchsia::bluetooth::gatt2::Handle handle,
::fuchsia::bluetooth::gatt2::ReadOptions options,
ReadDescriptorCallback callback) override;
void WriteDescriptor(::fuchsia::bluetooth::gatt2::Handle handle, ::std::vector<uint8_t> value,
::fuchsia::bluetooth::gatt2::WriteOptions options,
WriteDescriptorCallback callback) override;
void RegisterCharacteristicNotifier(
::fuchsia::bluetooth::gatt2::Handle handle,
::fidl::InterfaceHandle<::fuchsia::bluetooth::gatt2::CharacteristicNotifier> notifier,
RegisterCharacteristicNotifierCallback callback) override;
// Send the next notifier value in the queue if the client acknowledged the previous value.
void MaybeNotifyNextValue(NotifierId notifier_id);
void OnCharacteristicNotifierError(NotifierId notifier_id,
bt::gatt::CharacteristicHandle char_handle,
bt::gatt::IdType handler_id);
// The remote GATT service that backs this service.
bt::gatt::RemoteService::WeakPtr service_;
NotifierId next_notifier_id_ = 0u;
std::unordered_map<NotifierId, CharacteristicNotifier> characteristic_notifiers_;
// The peer that is serving this service.
bt::PeerId peer_id_;
WeakSelf<Gatt2RemoteServiceServer> weak_self_;
};
} // namespace bthost
#endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_FIDL_GATT2_REMOTE_SERVICE_SERVER_H_