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 <lib/fit/function.h> 18 19 #include <utility> 20 21 #include "lib/fidl/cpp/binding.h" 22 #include "lib/fidl/cpp/interface_request.h" 23 #include "pw_bluetooth_sapphire/internal/host/common/assert.h" 24 #include "pw_bluetooth_sapphire/internal/host/common/macros.h" 25 #include "pw_bluetooth_sapphire/internal/host/gap/adapter.h" 26 27 namespace bt { 28 29 namespace gap { 30 class Adapter; 31 } // namespace gap 32 33 namespace gatt { 34 class GATT; 35 } // namespace gatt 36 37 } // namespace bt 38 39 namespace bthost { 40 41 // This class acts as a common base type for all FIDL interface servers. Its 42 // main purpose is to provide type erasure for the ServerBase template below. 43 class Server { 44 public: 45 virtual ~Server() = default; 46 47 virtual void set_error_handler(fit::function<void(zx_status_t)> handler) = 0; 48 }; 49 50 // ServerBase is a common base implementation for FIDL interface servers. 51 template <typename Interface> 52 class ServerBase : public Server, public Interface { 53 public: 54 // Constructs a FIDL server by binding a fidl::InterfaceRequest. ServerBase(Interface * impl,fidl::InterfaceRequest<Interface> request)55 ServerBase(Interface* impl, fidl::InterfaceRequest<Interface> request) 56 : ServerBase(impl, request.TakeChannel()) {} 57 58 // Constructs a FIDL server by binding a zx::channel. ServerBase(Interface * impl,zx::channel channel)59 ServerBase(Interface* impl, zx::channel channel) 60 : binding_(impl, std::move(channel)) { 61 PW_DCHECK(binding_.is_bound()); 62 } 63 64 ~ServerBase() override = default; 65 set_error_handler(fit::function<void (zx_status_t)> handler)66 void set_error_handler(fit::function<void(zx_status_t)> handler) override { 67 binding_.set_error_handler(std::move(handler)); 68 } 69 70 protected: binding()71 ::fidl::Binding<Interface>* binding() { return &binding_; } 72 73 private: 74 // Holds the channel from the FIDL client. 75 ::fidl::Binding<Interface> binding_; 76 77 // Binding cannot be copied or moved. 78 BT_DISALLOW_COPY_ASSIGN_AND_MOVE(ServerBase); 79 }; 80 81 // Base template for GAP FIDL interface servers. The GAP profile is accessible 82 // through an Adapter object. 83 template <typename Interface> 84 class AdapterServerBase : public ServerBase<Interface> { 85 public: AdapterServerBase(bt::gap::Adapter::WeakPtr adapter,Interface * impl,fidl::InterfaceRequest<Interface> request)86 AdapterServerBase(bt::gap::Adapter::WeakPtr adapter, 87 Interface* impl, 88 fidl::InterfaceRequest<Interface> request) 89 : AdapterServerBase(adapter, impl, request.TakeChannel()) {} 90 AdapterServerBase(bt::gap::Adapter::WeakPtr adapter,Interface * impl,zx::channel channel)91 AdapterServerBase(bt::gap::Adapter::WeakPtr adapter, 92 Interface* impl, 93 zx::channel channel) 94 : ServerBase<Interface>(impl, std::move(channel)), 95 adapter_(std::move(adapter)) { 96 PW_DCHECK(adapter_.is_alive()); 97 } 98 99 ~AdapterServerBase() override = default; 100 101 protected: adapter()102 const bt::gap::Adapter::WeakPtr& adapter() const { return adapter_; } 103 104 private: 105 bt::gap::Adapter::WeakPtr adapter_; 106 107 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AdapterServerBase); 108 }; 109 110 // Base template for GATT FIDL interface servers. The GATT profile is accessible 111 // through an Adapter object. 112 template <typename Interface> 113 class GattServerBase : public ServerBase<Interface> { 114 public: GattServerBase(bt::gatt::GATT::WeakPtr gatt,Interface * impl,fidl::InterfaceRequest<Interface> request)115 GattServerBase(bt::gatt::GATT::WeakPtr gatt, 116 Interface* impl, 117 fidl::InterfaceRequest<Interface> request) 118 : ServerBase<Interface>(impl, std::move(request)), 119 gatt_(std::move(gatt)) { 120 PW_DCHECK(gatt_.is_alive()); 121 } 122 123 ~GattServerBase() override = default; 124 125 protected: gatt()126 bt::gatt::GATT::WeakPtr gatt() const { return gatt_; } 127 128 private: 129 bt::gatt::GATT::WeakPtr gatt_; 130 131 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(GattServerBase); 132 }; 133 134 } // namespace bthost 135