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 19 #include "lib/fidl/cpp/binding.h" 20 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/server_base.h" 21 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 22 #include "pw_bluetooth_sapphire/internal/host/gatt/gatt.h" 23 24 namespace bthost { 25 26 class Gatt2RemoteServiceServer 27 : public GattServerBase<fuchsia::bluetooth::gatt2::RemoteService> { 28 public: 29 // The maximum number of pending notification values per 30 // CharacteristicNotifier (for flow control). If exceeded, the notifier 31 // protocol is closed. 32 static const size_t kMaxPendingNotifierValues = 20; 33 34 Gatt2RemoteServiceServer( 35 bt::gatt::RemoteService::WeakPtr service, 36 bt::gatt::GATT::WeakPtr gatt, 37 bt::PeerId peer_id, 38 fidl::InterfaceRequest<fuchsia::bluetooth::gatt2::RemoteService> request); 39 ~Gatt2RemoteServiceServer() override; 40 41 void Close(zx_status_t status); 42 43 private: 44 using NotifierId = uint64_t; 45 46 struct CharacteristicNotifier { 47 bt::gatt::IdType handler_id; 48 bt::gatt::CharacteristicHandle characteristic_handle; 49 fidl::InterfacePtr<fuchsia::bluetooth::gatt2::CharacteristicNotifier> 50 notifier; 51 // For flow control, values are only sent when the client responds to the 52 // previous value with an acknowledgement. This variable stores the queued 53 // values. 54 std::queue<fuchsia::bluetooth::gatt2::ReadValue> queued_values; 55 // `last_value_ack` defaults to true so that the first notification queued 56 // up is sent to the FIDL client immediately. 57 bool last_value_ack = true; 58 }; 59 60 // fuchsia::bluetooth::gatt2::RemoteService overrides: 61 void DiscoverCharacteristics( 62 DiscoverCharacteristicsCallback callback) override; 63 64 void ReadByType(::fuchsia::bluetooth::Uuid uuid, 65 ReadByTypeCallback callback) override; 66 67 void ReadCharacteristic(::fuchsia::bluetooth::gatt2::Handle handle, 68 ::fuchsia::bluetooth::gatt2::ReadOptions options, 69 ReadCharacteristicCallback callback) override; 70 71 void WriteCharacteristic(::fuchsia::bluetooth::gatt2::Handle handle, 72 ::std::vector<uint8_t> value, 73 ::fuchsia::bluetooth::gatt2::WriteOptions options, 74 WriteCharacteristicCallback callback) override; 75 76 void ReadDescriptor(::fuchsia::bluetooth::gatt2::Handle handle, 77 ::fuchsia::bluetooth::gatt2::ReadOptions options, 78 ReadDescriptorCallback callback) override; 79 80 void WriteDescriptor(::fuchsia::bluetooth::gatt2::Handle handle, 81 ::std::vector<uint8_t> value, 82 ::fuchsia::bluetooth::gatt2::WriteOptions options, 83 WriteDescriptorCallback callback) override; 84 85 void RegisterCharacteristicNotifier( 86 ::fuchsia::bluetooth::gatt2::Handle handle, 87 ::fidl::InterfaceHandle< 88 ::fuchsia::bluetooth::gatt2::CharacteristicNotifier> notifier, 89 RegisterCharacteristicNotifierCallback callback) override; 90 91 // Send the next notifier value in the queue if the client acknowledged the 92 // previous value. 93 void MaybeNotifyNextValue(NotifierId notifier_id); 94 95 void OnCharacteristicNotifierError(NotifierId notifier_id, 96 bt::gatt::CharacteristicHandle char_handle, 97 bt::gatt::IdType handler_id); 98 99 // The remote GATT service that backs this service. 100 bt::gatt::RemoteService::WeakPtr service_; 101 102 NotifierId next_notifier_id_ = 0u; 103 std::unordered_map<NotifierId, CharacteristicNotifier> 104 characteristic_notifiers_; 105 106 // The peer that is serving this service. 107 bt::PeerId peer_id_; 108 109 WeakSelf<Gatt2RemoteServiceServer> weak_self_; 110 }; 111 112 } // namespace bthost 113