summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/adapter.c23
-rw-r--r--src/adv_monitor.c147
-rw-r--r--src/adv_monitor.h32
4 files changed, 204 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 725fbe48d..22b4fa30c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -293,7 +293,8 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
src/gatt-client.h src/gatt-client.c \
src/device.h src/device.c \
src/dbus-common.c src/dbus-common.h \
- src/eir.h src/eir.c
+ src/eir.h src/eir.c \
+ src/adv_monitor.h src/adv_monitor.c
src_bluetoothd_LDADD = lib/libbluetooth-internal.la \
gdbus/libgdbus-internal.la \
src/libshared-glib.la \
diff --git a/src/adapter.c b/src/adapter.c
index 1435e2bd7..df628a7fd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -77,6 +77,7 @@
#include "attrib-server.h"
#include "gatt-database.h"
#include "advertising.h"
+#include "adv_monitor.h"
#include "eir.h"
#define ADAPTER_INTERFACE "org.bluez.Adapter1"
@@ -272,6 +273,8 @@ struct btd_adapter {
struct btd_gatt_database *database;
struct btd_adv_manager *adv_manager;
+ struct btd_adv_monitor_manager *adv_monitor_manager;
+
gboolean initialized;
GSList *pin_callbacks;
@@ -6360,6 +6363,9 @@ static void adapter_remove(struct btd_adapter *adapter)
btd_adv_manager_destroy(adapter->adv_manager);
adapter->adv_manager = NULL;
+ btd_adv_monitor_manager_destroy(adapter->adv_monitor_manager);
+ adapter->adv_monitor_manager = NULL;
+
g_slist_free(adapter->pin_callbacks);
adapter->pin_callbacks = NULL;
@@ -8633,6 +8639,23 @@ static int adapter_register(struct btd_adapter *adapter)
adapter->adv_manager = btd_adv_manager_new(adapter, adapter->mgmt);
+ if (g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) {
+ if (adapter->supported_settings & MGMT_SETTING_LE) {
+ adapter->adv_monitor_manager =
+ btd_adv_monitor_manager_create(adapter,
+ adapter->mgmt);
+ if (!adapter->adv_monitor_manager) {
+ btd_error(adapter->dev_id,
+ "Failed to create Adv Monitor "
+ "Manager for adapter");
+ return -EINVAL;
+ }
+ } else {
+ btd_info(adapter->dev_id, "Adv Monitor Manager "
+ "skipped, LE unavailable");
+ }
+ }
+
db = btd_gatt_database_get_db(adapter->database);
adapter->db_id = gatt_db_register(db, services_modified,
services_modified,
diff --git a/src/adv_monitor.c b/src/adv_monitor.c
new file mode 100644
index 000000000..ad3f64cbe
--- /dev/null
+++ b/src/adv_monitor.c
@@ -0,0 +1,147 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2020 Google LLC
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdint.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#include "adapter.h"
+#include "dbus-common.h"
+#include "log.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/util.h"
+
+#include "adv_monitor.h"
+
+#define ADV_MONITOR_MGR_INTERFACE "org.bluez.AdvertisementMonitorManager1"
+
+struct btd_adv_monitor_manager {
+ struct btd_adapter *adapter;
+ struct mgmt *mgmt;
+ uint16_t adapter_id;
+};
+
+static const GDBusMethodTable adv_monitor_methods[] = {
+ { GDBUS_EXPERIMENTAL_METHOD("RegisterMonitor",
+ GDBUS_ARGS({ "application", "o" }),
+ NULL, NULL) },
+ { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterMonitor",
+ GDBUS_ARGS({ "application", "o" }),
+ NULL, NULL) },
+ { }
+};
+
+static const GDBusPropertyTable adv_monitor_properties[] = {
+ {"SupportedMonitorTypes", "as", NULL, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
+ {"SupportedFeatures", "as", NULL, NULL, NULL,
+ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
+ { }
+};
+
+/* Allocates a manager object */
+static struct btd_adv_monitor_manager *manager_new(
+ struct btd_adapter *adapter,
+ struct mgmt *mgmt)
+{
+ struct btd_adv_monitor_manager *manager;
+
+ if (!adapter || !mgmt)
+ return NULL;
+
+ manager = new0(struct btd_adv_monitor_manager, 1);
+ if (!manager)
+ return NULL;
+
+ manager->adapter = adapter;
+ manager->mgmt = mgmt_ref(mgmt);
+ manager->adapter_id = btd_adapter_get_index(adapter);
+
+ return manager;
+}
+
+/* Frees a manager object */
+static void manager_free(struct btd_adv_monitor_manager *manager)
+{
+ mgmt_unref(manager->mgmt);
+
+ free(manager);
+}
+
+/* Destroys a manager object and unregisters its D-Bus interface */
+static void manager_destroy(struct btd_adv_monitor_manager *manager)
+{
+ if (!manager)
+ return;
+
+ g_dbus_unregister_interface(btd_get_dbus_connection(),
+ adapter_get_path(manager->adapter),
+ ADV_MONITOR_MGR_INTERFACE);
+
+ manager_free(manager);
+}
+
+/* Creates a manager and registers its D-Bus interface */
+struct btd_adv_monitor_manager *btd_adv_monitor_manager_create(
+ struct btd_adapter *adapter,
+ struct mgmt *mgmt)
+{
+ struct btd_adv_monitor_manager *manager;
+
+ manager = manager_new(adapter, mgmt);
+ if (!manager)
+ return NULL;
+
+ if (!g_dbus_register_interface(btd_get_dbus_connection(),
+ adapter_get_path(manager->adapter),
+ ADV_MONITOR_MGR_INTERFACE,
+ adv_monitor_methods, NULL,
+ adv_monitor_properties, manager,
+ NULL)) {
+ btd_error(manager->adapter_id,
+ "Failed to register "
+ ADV_MONITOR_MGR_INTERFACE);
+ manager_free(manager);
+ return NULL;
+ }
+
+ btd_info(manager->adapter_id,
+ "Adv Monitor Manager created for adapter %s",
+ adapter_get_path(manager->adapter));
+
+ return manager;
+}
+
+/* Destroys a manager and unregisters its D-Bus interface */
+void btd_adv_monitor_manager_destroy(struct btd_adv_monitor_manager *manager)
+{
+ if (!manager)
+ return;
+
+ btd_info(manager->adapter_id, "Destroy Adv Monitor Manager");
+
+ manager_destroy(manager);
+}
diff --git a/src/adv_monitor.h b/src/adv_monitor.h
new file mode 100644
index 000000000..69ea348f8
--- /dev/null
+++ b/src/adv_monitor.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2020 Google LLC
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifndef __ADV_MONITOR_H
+#define __ADV_MONITOR_H
+
+struct mgmt;
+struct btd_adapter;
+struct btd_adv_monitor_manager;
+
+struct btd_adv_monitor_manager *btd_adv_monitor_manager_create(
+ struct btd_adapter *adapter,
+ struct mgmt *mgmt);
+void btd_adv_monitor_manager_destroy(struct btd_adv_monitor_manager *manager);
+
+#endif /* __ADV_MONITOR_H */