// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef PLATFORM_IMPL_LINUX_BLUETOOTH_BLUEZ_PROFILE_H_ #define PLATFORM_IMPL_LINUX_BLUETOOTH_BLUEZ_PROFILE_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" #include "internal/platform/implementation/linux/bluez.h" #include "internal/platform/implementation/linux/generated/dbus/bluez/profile_server.h" #include "internal/platform/implementation/linux/generated/dbus/bluez/profile_manager_client.h" #include "internal/platform/logging.h" namespace nearby { namespace linux { class Profile : public sdbus::AdaptorInterfaces { public: Profile(sdbus::IConnection &system_bus, absl::string_view profile_object_path, BluetoothDevices &devices) : AdaptorInterfaces(system_bus, std::string(profile_object_path)), released_(false), devices_(devices) { registerAdaptor(); NEARBY_LOGS(VERBOSE) << __func__ << ": Created a new BlueZ profile at :" << getObjectPath(); } ~Profile() { unregisterAdaptor(); } struct FDProperties { FDProperties(const std::map &fd_props) { if (fd_props.count("Version") == 1) { version = fd_props.at("Version"); } if (fd_props.count("Features") == 1) { features = fd_props.at("Features"); } } std::optional version; std::optional features; }; void Release() override; void NewConnection(const sdbus::ObjectPath &, const sdbus::UnixFd &, const std::map &) override; void RequestDisconnection(const sdbus::ObjectPath &) override; std::atomic_bool released_; absl::Mutex connections_lock_; std::map>> connections_; BluetoothDevices &devices_; }; class ProfileManager : private sdbus::ProxyInterfaces { public: ProfileManager(sdbus::IConnection &system_bus, BluetoothDevices &devices) : ProxyInterfaces(system_bus, bluez::SERVICE_DEST, "/org/bluez"), devices_(devices) { registerProxy(); } ~ProfileManager() { unregisterProxy(); } bool ProfileRegistered(absl::string_view service_uuid); bool Register(std::optional service_name, absl::string_view service_uuid); bool Register(absl::string_view service_uuid) { return Register(std::nullopt, service_uuid); } void Unregister(absl::string_view service_uuid); std::optional GetServiceRecordFD(api::BluetoothDevice &remote_device, absl::string_view service_uuid, CancellationFlag *cancellation_flag); std::optional< std::pair, sdbus::UnixFd>> GetServiceRecordFD(absl::string_view service_uuid); private: BluetoothDevices &devices_; // Maps service UUIDs to RegisteredService std::map> registered_services_; absl::Mutex registered_service_uuids_lock_; }; } // namespace linux } // namespace nearby #endif