mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Added GattProfile. Disabled fast adverts due to linux not supporting random mac addresses.
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user