blob: 884ac9b854b0c169a225e75e49ab58a2dd28e502 [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.
#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_FAKE_LAYER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_FAKE_LAYER_H_
#include "src/connectivity/bluetooth/core/bt-host/gatt/fake_client.h"
#include "src/connectivity/bluetooth/core/bt-host/gatt/gatt.h"
namespace bt::gatt::testing {
// This is a fake version of the root GATT object that can be injected in unit
// tests.
class FakeLayer final : public GATT {
public:
FakeLayer() = default;
~FakeLayer() override = default;
// Create a new peer GATT service. Creates a peer entry if it doesn't already exist.
// Replaces an existing service with the same handle if it exists.
// Notifies the remote service watcher if |notify| is true.
//
// Returns the fake remote service and a handle to the fake object.
//
// NOTE: the remote service watcher can also get triggered by calling DiscoverServices().
std::pair<fbl::RefPtr<RemoteService>, fxl::WeakPtr<FakeClient>> AddPeerService(
PeerId peer_id, const ServiceData& info, bool notify = false);
// Removes the service with start handle of |handle| and notifies service watcher.
void RemovePeerService(PeerId peer_id, att::Handle handle);
// Assign a callback to be notified when a service discovery has been requested.
using DiscoverServicesCallback = fit::function<void(PeerId, std::vector<UUID>)>;
void SetDiscoverServicesCallback(DiscoverServicesCallback cb);
// Assign the status that will be returned by the ListServices callback.
void set_list_services_status(att::Result<>);
// Ignore future calls to ListServices().
void stop_list_services() { pause_list_services_ = true; }
// Assign a callback to be notified when the persist service changed CCC callback is set.
using SetPersistServiceChangedCCCCallbackCallback = fit::function<void()>;
void SetSetPersistServiceChangedCCCCallbackCallback(
SetPersistServiceChangedCCCCallbackCallback cb);
// Assign a callback to be notified when the retrieve service changed CCC callback is set.
using SetRetrieveServiceChangedCCCCallbackCallback = fit::function<void()>;
void SetSetRetrieveServiceChangedCCCCallbackCallback(
SetRetrieveServiceChangedCCCCallbackCallback cb);
// Directly force the fake layer to call the persist service changed CCC callback, to test the
// GAP adapter and peer cache.
void CallPersistServiceChangedCCCCallback(PeerId peer_id, bool notify, bool indicate);
// Directly force the fake layer to call the retrieve service changed CCC callback, to test the
// GAP adapter and peer cache.
std::optional<ServiceChangedCCCPersistedData> CallRetrieveServiceChangedCCCCallback(
PeerId peer_id);
// GATT overrides:
void AddConnection(PeerId peer_id, std::unique_ptr<Client> client,
Server::FactoryFunction server_factory) override;
void RemoveConnection(PeerId peer_id) override;
void RegisterService(ServicePtr service, ServiceIdCallback callback, ReadHandler read_handler,
WriteHandler write_handler, ClientConfigCallback ccc_callback) override;
void UnregisterService(IdType service_id) override;
void SendUpdate(IdType service_id, IdType chrc_id, PeerId peer_id, ::std::vector<uint8_t> value,
IndicationCallback indicate_cb) override;
void UpdateConnectedPeers(IdType service_id, IdType chrc_id, ::std::vector<uint8_t> value,
IndicationCallback indicate_cb) override;
void SetPersistServiceChangedCCCCallback(PersistServiceChangedCCCCallback callback) override;
void SetRetrieveServiceChangedCCCCallback(RetrieveServiceChangedCCCCallback callback) override;
void DiscoverServices(PeerId peer_id, std::vector<UUID> service_uuids) override;
RemoteServiceWatcherId RegisterRemoteServiceWatcherForPeer(PeerId peer_id,
RemoteServiceWatcher watcher) override;
bool UnregisterRemoteServiceWatcher(RemoteServiceWatcherId watcher_id) override;
void ListServices(PeerId peer_id, std::vector<UUID> uuids, ServiceListCallback callback) override;
fbl::RefPtr<RemoteService> FindService(PeerId peer_id, IdType service_id) override;
private:
// Test callbacks
DiscoverServicesCallback discover_services_cb_;
SetPersistServiceChangedCCCCallbackCallback set_persist_service_changed_ccc_cb_cb_;
SetRetrieveServiceChangedCCCCallbackCallback set_retrieve_service_changed_ccc_cb_cb_;
// Emulated callbacks
std::unordered_map<PeerId, RemoteServiceWatcher> remote_service_watchers_;
PersistServiceChangedCCCCallback persist_service_changed_ccc_cb_;
RetrieveServiceChangedCCCCallback retrieve_service_changed_ccc_cb_;
att::Result<> list_services_status_ = fitx::ok();
bool pause_list_services_ = false;
// Emulated GATT peer.
struct TestPeer {
TestPeer();
~TestPeer();
FakeClient fake_client;
std::unordered_map<IdType, fbl::RefPtr<RemoteService>> services;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TestPeer);
};
std::unordered_map<PeerId, TestPeer> peers_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FakeLayer);
};
} // namespace bt::gatt::testing
#endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GATT_FAKE_LAYER_H_