Added GattProfile. Disabled fast adverts due to linux not supporting random mac addresses.

This commit is contained in:
kidfromjupiter
2026-01-12 08:17:05 +00:00
parent 3d97a540b5
commit 329f2ce2c9
15 changed files with 219 additions and 27 deletions
@@ -76,6 +76,7 @@ cc_library(
# "bluez_gatt_characteristic_client.h",
"bluez_gatt_characteristic_server.h",
"bluez_gatt_manager.h",
"bluez_gatt_profile.h",
# "bluez_gatt_service_client.h",
"bluez_gatt_service_server.h",
"bluez_le_advertisement.h",
@@ -54,18 +54,24 @@ GattServer::CreateCharacteristic(
<< "' and message '" << e.getMessage() << "'";
return std::nullopt;
}
auto profile = std::make_unique<bluez::GattProfile> (system_bus_, bluez::gatt_profile_object_path(
std::string(service_uuid)), std::string(service_uuid));
profile -> emitInterfacesAddedSignal();
if (service->AddCharacteristic(service_uuid, characteristic_uuid, permission,
property)) {
bluez::GattManager manager(system_bus_, adapter_.GetObjectPath());
try {
LOG(INFO) << __func__ << ": registering service "
<< service->getObjectPath();
manager.RegisterApplication("/", {});
} catch (const sdbus::Error& e) {
DBUS_LOG_METHOD_CALL_ERROR(&manager, "RegisterApplication", e);
return std::nullopt;
}
try {
LOG(INFO)<< __func__ << ": Registering service on gattmanager";
gatt_manager_ -> RegisterApplication(gatt_service_root_object_manager -> getObjectPath(), {});
} catch (const sdbus::Error& e) {
LOG(ERROR)
<< __func__
<< ": error calling RegisterAplication for GattManager with object path "
<< gatt_manager_->getObjectPath() << " with name '" << e.getName()
<< "' and message '" << e.getMessage() << "'";
return std::nullopt;
}
services_.insert({service_uuid, std::move(service)});
@@ -20,6 +20,8 @@
#include <sdbus-c++/IConnection.h>
#include "bluez_gatt_manager.h"
#include "bluez_gatt_profile.h"
#include "absl/container/flat_hash_map.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/optional.h"
@@ -63,6 +65,8 @@ class GattServer : public api::ble_v2::GattServer {
devices_(std::move(devices)),
adapter_(adapter),
local_peripheral_(adapter_),
gatt_service_root_object_manager(std::make_unique<RootObjectManager>(system_bus_, "/com/google/nearby/medium/ble/gatt")),
gatt_manager_(std::make_unique<bluez::GattManager>(system_bus_, adapter_.GetObjectPath())),
server_cb_(std::make_shared<api::ble_v2::ServerGattConnectionCallback>(
std::move(server_cb))) {}
~GattServer() override = default;
@@ -85,6 +89,11 @@ class GattServer : public api::ble_v2::GattServer {
BluetoothAdapter adapter_;
LocalBlePeripheral local_peripheral_;
std::unique_ptr<RootObjectManager> gatt_service_root_object_manager;
absl::Mutex profiles_mutex_;
absl::flat_hash_map<Uuid, std::unique_ptr<bluez::GattProfile>> gatt_profiles_;
ABSL_GUARDED_BY(profiles_mutex_)
std::unique_ptr<bluez::GattManager> gatt_manager_;
std::shared_ptr<api::ble_v2::ServerGattConnectionCallback> server_cb_;
absl::Mutex services_mutex_;
absl::flat_hash_map<Uuid, std::unique_ptr<bluez::GattServiceServer>> services_
@@ -0,0 +1,33 @@
// 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.
#include "internal/platform/implementation/linux/ble_medium.h"
#include <memory>
#include <string>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/linux/ble_v2_medium.h"
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
#include "internal/platform/logging.h"
#include "internal/platform/uuid.h"
namespace nearby {
namespace linux {
} // namespace linux
} // namespace nearby
@@ -43,7 +43,7 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
devices_(std::make_unique<BluetoothDevices>(
system_bus_, adapter_.GetObjectPath(), observers_)),
// gatt_discovery_(std::make_shared<BluezGattDiscovery>(system_bus_)),
root_object_manager_(std::make_unique<RootObjectManager>(*system_bus_)),
root_object_manager_(std::make_unique<RootObjectManager>(*system_bus_, "/com/google/nearby/medium/ble/advertisement/monitor")),
adv_monitor_manager_(
bluez::AdvertisementMonitorManager::
DiscoverAdvertisementMonitorManager(*system_bus_, adapter_)),
@@ -56,7 +56,7 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
<< ": Registering path /com/google/nearby/medium/ble/advertisement/monitor with AdvertisementMonitorManager at "
<< adv_monitor_manager_->getObjectPath();
try {
adv_monitor_manager_->RegisterMonitor("/com/google/nearby/medium/ble/advertisement/monitor");
adv_monitor_manager_->RegisterMonitor(root_object_manager_->getObjectPath());
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(adv_monitor_manager_, "RegisterMonitor", e);
}
@@ -73,6 +73,11 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
bool BleV2Medium::StartAdvertising(
const api::ble_v2::BleAdvertisementData &advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters) {
if (!advertising_data.is_extended_advertisement)
{
// can't send two LE advertisements at the same
return true;
}
if (!adapter_.IsEnabled()) {
LOG(WARNING) << "BLE cannot start advertising because the "
"bluetooth adapter is not enabled.";
@@ -26,6 +26,7 @@
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble_v2.h"
// #include "internal/platform/implementation/linux/ble_gatt_client.h"
#include "bluez_gatt_manager.h"
#include "internal/platform/implementation/linux/ble_v2_server_socket.h"
#include "internal/platform/implementation/linux/bluetooth_adapter.h"
#include "internal/platform/implementation/linux/bluetooth_devices.h"
@@ -142,7 +143,7 @@ class BleV2Medium final : public api::ble_v2::BleMedium {
std::shared_ptr<BluetoothDevices> devices_;
// std::shared_ptr<BluezGattDiscovery> gatt_discovery_;
std::unique_ptr<RootObjectManager> root_object_manager_;
std::unique_ptr<RootObjectManager> root_object_manager_;
std::unique_ptr<bluez::AdvertisementMonitorManager> adv_monitor_manager_;
absl::Mutex active_adv_monitors_mutex_;
absl::flat_hash_map<
@@ -116,7 +116,8 @@ void MonitoredBluetoothDevice::onPropertiesChanged(
}
for (auto it = changedProperties.begin(); it != changedProperties.end();
it++) {
it++)
{
if (it->first == bluez::DEVICE_PROP_ADDRESS) {
LOG(INFO) << __func__ << ": " << getObjectPath()
<< ": Notifying observers about address change";
@@ -124,6 +125,7 @@ void MonitoredBluetoothDevice::onPropertiesChanged(
for (const auto &observer : observers_.GetObservers()) {
observer->DeviceAddressChanged(*this, address);
}
} else if (it->first == bluez::DEVICE_PROP_PAIRED) {
LOG(INFO) << __func__ << ": " << getObjectPath()
<< "Notifying observers about paired status change.";
@@ -137,7 +139,9 @@ void MonitoredBluetoothDevice::onPropertiesChanged(
for (const auto &observer : observers_.GetObservers()) {
observer->DeviceConnectedStateChanged(*this, it->second);
}
} else if (it->first == bluez::DEVICE_NAME) {
} else if ( it -> first == "ServicesResolved"){
LOG(INFO) << ": ServicesResolved";
}else if (it->first == bluez::DEVICE_NAME) {
auto callback = GetDiscoveryCallback();
if (callback != nullptr && callback->device_name_changed_cb != nullptr)
callback->device_name_changed_cb(*this);
@@ -35,7 +35,13 @@ sdbus::ObjectPath profile_object_path(absl::string_view service_uuid) {
absl::StrReplaceAll(service_uuid, {{"-", "_"}}));
}
sdbus::ObjectPath adapter_object_path(absl::string_view name) {
sdbus::ObjectPath gatt_profile_object_path(absl::string_view service_uuid) {
return absl::Substitute(
"$0/profile_$1",
NEARBY_BLE_GATT_PROFILE_PATH_ROOT,
absl::StrReplaceAll(service_uuid, {{"-", "_"}}));
}
sdbus::ObjectPath adapter_object_path(absl::string_view name) {
return absl::Substitute("/org/bluez/$0", name);
}
@@ -49,10 +49,13 @@ static constexpr const char *DEVICE_NAME = "Name";
static constexpr const char *NEARBY_BLE_GATT_PATH_ROOT =
"/com/google/nearby/medium/ble/gatt";
std::string device_object_path(const sdbus::ObjectPath &adapter_object_path,
static constexpr const char *NEARBY_BLE_GATT_PROFILE_PATH_ROOT =
"/com/google/nearby/medium/ble/gatt/profile";
std::string device_object_path(const sdbus::ObjectPath &adapter_object_path,
absl::string_view mac_address);
sdbus::ObjectPath profile_object_path(absl::string_view service_uuid);
sdbus::ObjectPath adapter_object_path(absl::string_view name);
sdbus::ObjectPath gatt_profile_object_path(absl::string_view service_uuid);
sdbus::ObjectPath gatt_service_path(size_t num);
sdbus::ObjectPath gatt_characteristic_path(
const sdbus::ObjectPath &service_path, size_t num);
@@ -1,4 +1,7 @@
#include "internal/platform/implementation/linux/bluez_advertisement_monitor.h"
#include <regex>
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/linux/dbus.h"
@@ -57,7 +60,9 @@ void AdvertisementMonitor::DeviceFound(const sdbus::ObjectPath &device) {
adv_data.service_data.emplace(*uuid,
std::string(bytes.begin(), bytes.end()));
}
// scan_callback_.advertisement_found_cb(*peripheral, adv_data);
auto id = std::stoull(std::regex_replace(peripheral->GetMacAddress(),
std::regex("[:\\-]"), ""), nullptr, 16);
scan_callback_.advertisement_found_cb(id, adv_data);
}
void AdvertisementMonitor::DeviceLost(const sdbus::ObjectPath &device) {
@@ -31,10 +31,11 @@ class AdvertisementMonitorManager final
org::bluez::AdvertisementMonitorManager1_proxy> {
private:
friend std::unique_ptr<AdvertisementMonitorManager>
std::make_unique<AdvertisementMonitorManager>(sdbus::IConnection &,
const BluetoothAdapter &);
AdvertisementMonitorManager(sdbus::IConnection &system_bus,
const BluetoothAdapter &adapter)
std::make_unique<AdvertisementMonitorManager>(
sdbus::IConnection &, const ::nearby::linux::BluetoothAdapter &);
AdvertisementMonitorManager(
sdbus::IConnection &system_bus,
const ::nearby::linux::BluetoothAdapter &adapter)
: ProxyInterfaces(system_bus, "org.bluez", adapter.GetObjectPath()) {
registerProxy();
}
@@ -49,8 +50,9 @@ class AdvertisementMonitorManager final
~AdvertisementMonitorManager() { unregisterProxy(); }
static std::unique_ptr<AdvertisementMonitorManager>
DiscoverAdvertisementMonitorManager(sdbus::IConnection &system_bus,
const BluetoothAdapter &adapter) {
DiscoverAdvertisementMonitorManager(
sdbus::IConnection &system_bus,
const ::nearby::linux::BluetoothAdapter &adapter) {
bluez::BluezObjectManager manager(system_bus);
std::map<sdbus::ObjectPath,
std::map<std::string, std::map<std::string, sdbus::Variant>>>
@@ -0,0 +1,63 @@
//
// Created by root on 1/11/26.
//
#ifndef WORKSPACE_BLUEZ_GATT_PROFILE_H
#define WORKSPACE_BLUEZ_GATT_PROFILE_H
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/ProxyInterfaces.h>
#include <sdbus-c++/Types.h>
#include "generated/dbus/bluez/gatt_profile_server.h"
#include "internal/platform/logging.h"
#include <algorithm>
#include <cctype>
#include <string>
namespace nearby {
namespace linux {
namespace bluez {
class GattProfile
: public sdbus::AdaptorInterfaces<org::bluez::GattProfile1_adaptor, sdbus::ManagedObject_adaptor> {
public:
GattProfile(const GattProfile &) = delete;
GattProfile(GattProfile &&) = delete;
GattProfile &operator=(const GattProfile &) = delete;
GattProfile &operator=(GattProfile &&) = delete;
GattProfile(sdbus::IConnection &system_bus,
sdbus::ObjectPath profile_path, std::string service_uuid)
: AdaptorInterfaces(system_bus, profile_path),
uuids_({service_uuid})
{
registerAdaptor();
}
~GattProfile() { unregisterAdaptor(); }
void Release() override
{
LOG(INFO) << __func__ << ": Gatt profile released";
};
private:
std::string ToLowerAscii(std::string s) {
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
return s;
}
std::vector<std::string> UUIDs() override
{
LOG(INFO)<< __func__ << ": UUIDs called, returned: " << ToLowerAscii(uuids_[0]);
return uuids_;
};
std::vector<std::string> uuids_;
};
} // namespace bluez
} // namespace linux
} // namespace nearby
#endif //WORKSPACE_BLUEZ_GATT_PROFILE_H
@@ -51,10 +51,8 @@ class RootObjectManager final
: public sdbus::AdaptorInterfaces<sdbus::ObjectManager_adaptor,
sdbus::Properties_adaptor> {
public:
// only used in ble advertisement monitoring for now.
// TODO: Remove hardcodinged va
explicit RootObjectManager(sdbus::IConnection &system_bus)
: AdaptorInterfaces(system_bus, "/com/google/nearby/medium/ble/advertisement/monitor") {
explicit RootObjectManager(sdbus::IConnection &system_bus, sdbus::ObjectPath path)
: AdaptorInterfaces(system_bus, path) {
registerAdaptor();
}
~RootObjectManager() { unregisterAdaptor(); }
@@ -0,0 +1,48 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp___home_lasan_Dev_nearby_latest_internal_platform_implementation_linux_generated_dbus_bluez_gatt_profile_server_h__adaptor__H__
#define __sdbuscpp___home_lasan_Dev_nearby_latest_internal_platform_implementation_linux_generated_dbus_bluez_gatt_profile_server_h__adaptor__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace bluez {
class GattProfile1_adaptor
{
public:
static constexpr const char* INTERFACE_NAME = "org.bluez.GattProfile1";
protected:
GattProfile1_adaptor(sdbus::IObject& object)
: object_(&object)
{
object_->registerMethod("Release").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->Release(); });
object_->registerProperty("UUIDs").onInterface(INTERFACE_NAME).withGetter([this](){ return this->UUIDs(); });
}
GattProfile1_adaptor(const GattProfile1_adaptor&) = delete;
GattProfile1_adaptor& operator=(const GattProfile1_adaptor&) = delete;
GattProfile1_adaptor(GattProfile1_adaptor&&) = default;
GattProfile1_adaptor& operator=(GattProfile1_adaptor&&) = default;
~GattProfile1_adaptor() = default;
private:
virtual void Release() = 0;
private:
virtual std::vector<std::string> UUIDs() = 0;
private:
sdbus::IObject* object_;
};
}} // namespaces
#endif
@@ -0,0 +1,8 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.bluez.GattProfile1">
<method name="Release"/>
<property name="UUIDs" type="as" access="read"/>
</interface>
</node>