1 // Copyright 2024 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 17 #include <fuchsia/bluetooth/gatt2/cpp/fidl.h> 18 #include <lib/fidl/cpp/binding.h> 19 20 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/gatt2_remote_service_server.h" 21 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/server_base.h" 22 #include "pw_bluetooth_sapphire/internal/host/gatt/gatt.h" 23 24 namespace bthost { 25 class Gatt2ClientServer 26 : public GattServerBase<fuchsia::bluetooth::gatt2::Client> { 27 public: 28 // |error_cb| will be called if the FIDL client closed the protocol or an 29 // error occurs and this server should be destroyed. 30 Gatt2ClientServer( 31 bt::gatt::PeerId peer_id, 32 bt::gatt::GATT::WeakPtr weak_gatt, 33 fidl::InterfaceRequest<fuchsia::bluetooth::gatt2::Client> request, 34 fit::callback<void()> error_cb); 35 ~Gatt2ClientServer() override; 36 37 private: 38 using WatchServicesCallbackOnce = 39 fit::callback<void(std::vector<::fuchsia::bluetooth::gatt2::ServiceInfo>, 40 std::vector<::fuchsia::bluetooth::gatt2::Handle>)>; 41 using WatchServicesRequest = WatchServicesCallbackOnce; 42 43 using ServiceMap = 44 std::unordered_map<bt::att::Handle, bt::gatt::RemoteService::WeakPtr>; 45 46 struct WatchServicesResult { 47 std::unordered_set<bt::att::Handle> removed; 48 ServiceMap updated; 49 }; 50 51 void OnWatchServicesResult(const std::vector<bt::att::Handle>& removed, 52 const bt::gatt::ServiceList& added, 53 const bt::gatt::ServiceList& modified); 54 55 void TrySendNextWatchServicesResult(); 56 57 // fuchsia::bluetooth::gatt2::Client overrides: 58 void WatchServices(std::vector<::fuchsia::bluetooth::Uuid> fidl_uuids, 59 WatchServicesCallback callback) override; 60 void ConnectToService( 61 fuchsia::bluetooth::gatt2::ServiceHandle handle, 62 fidl::InterfaceRequest<fuchsia::bluetooth::gatt2::RemoteService> request) 63 override; 64 65 // The ID of the peer that this client is attached to. 66 bt::gatt::PeerId peer_id_; 67 68 // Callback provided by this server's owner that handles fatal errors (by 69 // closing this server). 70 fit::callback<void()> server_error_cb_; 71 72 // If a service's handle maps to a null value, a connection request to that 73 // service is in progress. 74 // TODO(fxbug.dev/42165614): Once FindService() returns the service directly, 75 // don't use null values. 76 std::unordered_map<bt::att::Handle, std::unique_ptr<Gatt2RemoteServiceServer>> 77 services_; 78 79 // False initially, and set to true after GATT::ListServices() completes. 80 // Set to false again if WatchServices() is called with a new UUID list. 81 bool list_services_complete_ = false; 82 83 // UUIDs of the previous WatchServices() call, if any. 84 std::unordered_set<bt::UUID> prev_watch_services_uuids_; 85 std::optional<WatchServicesRequest> watch_services_request_; 86 87 // Between clients calls to WatchServices, service watcher results are 88 // accumulated here. 89 std::optional<WatchServicesResult> next_watch_services_result_; 90 91 bt::gatt::GATT::RemoteServiceWatcherId service_watcher_id_; 92 93 // Must be the last member of this class. 94 WeakSelf<Gatt2ClientServer> weak_self_; 95 96 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Gatt2ClientServer); 97 }; 98 } // namespace bthost 99