From patchwork Tue Aug 18 22:26:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722253 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CBD93913 for ; Tue, 18 Aug 2020 22:27:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A8F4020786 for ; Tue, 18 Aug 2020 22:27:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="T+Dhckw0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726963AbgHRW1u (ORCPT ); Tue, 18 Aug 2020 18:27:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726799AbgHRW1t (ORCPT ); Tue, 18 Aug 2020 18:27:49 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9857DC061389 for ; Tue, 18 Aug 2020 15:27:49 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id ha11so186792pjb.1 for ; Tue, 18 Aug 2020 15:27:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KsHmEUXwiQyn5utGyEsVoXWZuKrts5eX54vDNQPsdd4=; b=T+Dhckw0Jxs03Z5Rn4qkNswc8C6ERDbn/tx5rkXCcizj2XnLuufLIvrg4vSfHN6bz+ zcAAfsLjhWYRULYmBlMeRzHmAlwy3R3hULRb74r0XPqh05bUAekEgPXm7RaK7MzFdUrB 26Ak5OlIX8znjbodxiqfztN2NlghAus6EqKYI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=KsHmEUXwiQyn5utGyEsVoXWZuKrts5eX54vDNQPsdd4=; b=L3S6NjT/+fs39h+4N3npt8WjcU4Bei1lZd4EpHOdbOK7D78BPQywoMgXqI1gPZ3JQm XXbQlyBZUhGWH/r6dSHn8L2KuWJHecZDfKZMNzBhAzTxU9iQsfKz337hu1gLF8XTes/n 1mt66eLUlAS5+efDKn3EPZBYw8cWIkF1ysObXL8HH8GHSWnJZeB0T1laI/ki/4e0+eHr SWvNMdZ/Dp4FQwIAATnz2uFzc6EbVsAa1aWc2AWTFZLaC6TziGMH+ZfxXTO35zYfHw+a xUuKmmgXotLb7P+rEgaGNaEr3CPay5TM9AT+jwfRnBpCpxmg9zGifL9muYxr537p2bud mEpQ== X-Gm-Message-State: AOAM531K4LLksX2fYEOj8icmWuBFTdYcGW0Y4gHSH0DCj2TGJvIkk0jp wHM+0Oq1HgXlxVmwUqxGyVPHVoc66uKS+Q== X-Google-Smtp-Source: ABdhPJwZZwCua3mViDmCIKqsJa1pIqXVd5lv66RM0icnNYHOdIBO+Xq7GuEiB77XwrXLheq7ANkGfw== X-Received: by 2002:a17:902:16a:: with SMTP id 97mr16976203plb.207.1597789667672; Tue, 18 Aug 2020 15:27:47 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.27.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:27:46 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v1 1/7] adv_monitor: Introduce org.bluez.AdvertisementMonitorManager1 interface Date: Tue, 18 Aug 2020 15:26:35 -0700 Message-Id: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This introduces the org.bluez.AdvertisementMonitorManager1 without implementing handlers of methods and properties. The following test was performed. - Upon adapter registration, the info line of creating an ADV monitor manager gets printed, and system bus emits the interface events of org.bluez.AdvertisementMonitorManager1. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik Reviewed-by: Abhishek Pandit-Subedi --- Makefile.am | 3 +- src/adapter.c | 14 +++++ src/adapter.h | 3 + src/adv_monitor.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ src/adv_monitor.h | 32 ++++++++++ 5 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 src/adv_monitor.c create mode 100644 src/adv_monitor.h diff --git a/Makefile.am b/Makefile.am index 7719c06f8..b14ee950e 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 5e896a9f0..41e9de286 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; @@ -6346,6 +6349,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; @@ -8623,6 +8629,14 @@ static int adapter_register(struct btd_adapter *adapter) adapter->adv_manager = btd_adv_manager_new(adapter, adapter->mgmt); + 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; + } + db = btd_gatt_database_get_db(adapter->database); adapter->db_id = gatt_db_register(db, services_modified, services_modified, diff --git a/src/adapter.h b/src/adapter.h index f8ac20261..5cb467141 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -26,6 +26,9 @@ #include #include +#include "lib/bluetooth.h" +#include "lib/sdp.h" + #define MAX_NAME_LENGTH 248 /* Invalid SSP passkey value used to indicate negative replies */ diff --git a/src/adv_monitor.c b/src/adv_monitor.c new file mode 100644 index 000000000..7044d3cca --- /dev/null +++ b/src/adv_monitor.c @@ -0,0 +1,149 @@ +/* + * + * 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 +#endif + +#define _GNU_SOURCE +#include + +#include +#include +#include + +#include "adapter.h" +#include "dbus-common.h" +#include "log.h" +#include "src/shared/mgmt.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; + char *path; +}; + +static const GDBusMethodTable adv_monitor_methods[] = { + { GDBUS_METHOD("RegisterMonitor", + GDBUS_ARGS({ "application", "o" }), + NULL, NULL) }, + { GDBUS_ASYNC_METHOD("UnregisterMonitor", + GDBUS_ARGS({ "application", "o" }), + NULL, NULL) }, + { } +}; + +static const GDBusPropertyTable adv_monitor_properties[] = { + {"SupportedMonitorTypes", "as", NULL, NULL, NULL}, + {"SupportedFeatures", "as", NULL, NULL, NULL}, + { } +}; + +/* 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 = g_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); + manager->path = g_strdup(adapter_get_path(manager->adapter)); + + return manager; +} + +/* Frees a manager object */ +static void manager_free(struct btd_adv_monitor_manager *manager) +{ + manager->adapter = NULL; + mgmt_unref(manager->mgmt); + manager->mgmt = NULL; + g_free(manager->path); + manager->path = NULL; + + g_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(), + manager->path, + 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(), manager->path, + ADV_MONITOR_MGR_INTERFACE, + adv_monitor_methods, NULL, + adv_monitor_properties, manager, NULL) + == FALSE) { + 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 */ From patchwork Tue Aug 18 22:26:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722255 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80183913 for ; Tue, 18 Aug 2020 22:28:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 633A020738 for ; Tue, 18 Aug 2020 22:28:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Sx1sJ4D/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726863AbgHRW2V (ORCPT ); Tue, 18 Aug 2020 18:28:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726539AbgHRW2T (ORCPT ); Tue, 18 Aug 2020 18:28:19 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0EE9C061389 for ; Tue, 18 Aug 2020 15:28:19 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id mt12so185013pjb.4 for ; Tue, 18 Aug 2020 15:28:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vKJ+f/QmyMYNU6dao3M/rrJbJatyE8JsrAuSYL+1TOQ=; b=Sx1sJ4D/Jj+OxwB14Esl7d7y4DFtoFs/Dqdf9infowX8dkY6nEsM+egVf5HAH2vw2v aV46lwbw5fJQIdF+U9g1LWjCIT9eY/m5+TjTnwXX5ZaX8EeDjGaXqXAbVrZtnx+AvmDM usHMbCC/r7oQX5PZiB+TkrHoL2ofLksjtw3GI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vKJ+f/QmyMYNU6dao3M/rrJbJatyE8JsrAuSYL+1TOQ=; b=DLHp0iPXgIORaEN2cH8aOGY+yxYQYEb8Ba8X9N8bSILQJ7Fd0p2/yaWQGpBMRsROet syY/pNrDxUsCgbg4+HRIuEL46VUWJDYBCtUXRGGVT5FzlxjOFKKPy3C6jWw0c07bCfAO HTAj4dMwQoufVQ2mfI+U7J2z74aP8Kdo6HpAJyd0GyCfXikdKM+F2kBJMDUpQ+rtxq4n 3qBeh3qO0Ol7+y+O08tj10YVBmiHAVhPVdifKo7vGywrxyr8xLUzvSyrzeP/bjSoLFEZ jUfH5jvVjxHueKKw/5Vtge1C1Jsf3p8ppr1Csx302RmGDpKqxo6Q0bB9nARU73iFVtGT 3QPw== X-Gm-Message-State: AOAM531KThShjQDxW/bvWS6bWQ+lISjw8BCVjX1/hJWsmra/7NV+MBv/ PU2Mi+lFOyuSh0YtMQkjUH7EHR4rz414mQ== X-Google-Smtp-Source: ABdhPJzkH+85uFFfO7XW7FzfEsmR/amlr1Dbh1aDkPzdkKTJ61ghfRYbiuHqdGExKzQ+P82lxYGKsA== X-Received: by 2002:a17:90b:2388:: with SMTP id mr8mr1780184pjb.64.1597789698910; Tue, 18 Aug 2020 15:28:18 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.28.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:28:18 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v1 2/7] adv_monitor: Implement Get functions of ADV monitor manager properties Date: Tue, 18 Aug 2020 15:26:37 -0700 Message-Id: <20200818152612.BlueZ.v1.2.I9960e45d36be3edb5f17de025e7eb8257d3cddef@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This implements the Get functions of SupportedMonitorTypes and SupportedFeatures. The following test was performed. - Issue dbus-send to read SupportedMonitorTypes and SupportedFeatures. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik Reviewed-by: Abhishek Pandit-Subedi --- src/adv_monitor.c | 130 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 7044d3cca..4d02237e8 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -28,10 +28,14 @@ #include #include +#include "lib/bluetooth.h" +#include "lib/mgmt.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" @@ -42,6 +46,12 @@ struct btd_adv_monitor_manager { struct mgmt *mgmt; uint16_t adapter_id; char *path; + + uint32_t supported_features; /* MGMT_ADV_MONITOR_FEATURE_MASK_* */ + uint32_t enabled_features; /* MGMT_ADV_MONITOR_FEATURE_MASK_* */ + uint16_t max_num_monitors; + uint8_t max_num_patterns; + }; static const GDBusMethodTable adv_monitor_methods[] = { @@ -54,9 +64,78 @@ static const GDBusMethodTable adv_monitor_methods[] = { { } }; +enum monitor_type { + MONITOR_TYPE_OR_PATTERNS, +}; + +const struct adv_monitor_type { + enum monitor_type type; + const char *name; +} supported_types[] = { + { MONITOR_TYPE_OR_PATTERNS, "or_patterns" }, + { }, +}; + +/* Gets SupportedMonitorTypes property */ +static gboolean get_supported_monitor_types(const GDBusPropertyTable *property, + DBusMessageIter *iter, + void *data) +{ + DBusMessageIter entry; + const struct adv_monitor_type *t; + struct btd_adv_monitor_manager *manager = data; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, + &entry); + + for (t = supported_types; t->name; t++) { + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, + &t->name); + } + + dbus_message_iter_close_container(iter, &entry); + + return TRUE; +} + +const struct adv_monitor_feature { + uint32_t mask; + const char *name; +} supported_features[] = { + { MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS, "controller-patterns" }, + { } +}; + +/* Gets SupportedFeatures property */ +static gboolean get_supported_features(const GDBusPropertyTable *property, + DBusMessageIter *iter, + void *data) +{ + DBusMessageIter entry; + const struct adv_monitor_feature *f; + struct btd_adv_monitor_manager *manager = data; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, + &entry); + + for (f = supported_features; f->name; f++) { + if (manager->supported_features & f->mask) { + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, + &f->name); + } + } + + dbus_message_iter_close_container(iter, &entry); + + return TRUE; +} + static const GDBusPropertyTable adv_monitor_properties[] = { - {"SupportedMonitorTypes", "as", NULL, NULL, NULL}, - {"SupportedFeatures", "as", NULL, NULL, NULL}, + {"SupportedMonitorTypes", "as", get_supported_monitor_types, NULL, + NULL}, + {"SupportedFeatures", "as", get_supported_features, NULL, NULL}, { } }; @@ -107,6 +186,42 @@ static void manager_destroy(struct btd_adv_monitor_manager *manager) manager_free(manager); } +/* Initiates manager's members based on the return of + * MGMT_OP_READ_ADV_MONITOR_FEATURES + */ +static void read_adv_monitor_features_cb(uint8_t status, uint16_t length, + const void *param, + void *user_data) +{ + const struct mgmt_rp_read_adv_monitor_features *rp = param; + struct btd_adv_monitor_manager *manager = user_data; + + if (status != MGMT_STATUS_SUCCESS || !param) { + btd_error(manager->adapter_id, "Failed to Read Adv Monitor " + "Features with status 0x%02x", status); + return; + } + + if (length < sizeof(*rp)) { + btd_error(manager->adapter_id, + "Wrong size of Read Adv Monitor Features " + "response"); + return; + } + + manager->supported_features = le32_to_cpu(rp->supported_features); + manager->enabled_features = le32_to_cpu(rp->enabled_features); + manager->max_num_monitors = le16_to_cpu(rp->max_num_handles); + manager->max_num_patterns = rp->max_num_patterns; + + btd_info(manager->adapter_id, "Adv Monitor Manager created with " + "supported features:0x%08x, enabled features:0x%08x, " + "max number of supported monitors:%d, " + "max number of supported patterns:%d", + manager->supported_features, manager->enabled_features, + manager->max_num_monitors, manager->max_num_patterns); +} + /* Creates a manager and registers its D-Bus interface */ struct btd_adv_monitor_manager *btd_adv_monitor_manager_create( struct btd_adapter *adapter, @@ -130,9 +245,14 @@ struct btd_adv_monitor_manager *btd_adv_monitor_manager_create( return NULL; } - btd_info(manager->adapter_id, - "Adv Monitor Manager created for adapter %s", - adapter_get_path(manager->adapter)); + if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_MONITOR_FEATURES, + manager->adapter_id, 0, NULL, + read_adv_monitor_features_cb, manager, NULL)) { + btd_error(manager->adapter_id, + "Failed to send Read Adv Monitor Features"); + manager_destroy(manager); + return NULL; + } return manager; } From patchwork Tue Aug 18 22:26:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722257 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 64805913 for ; Tue, 18 Aug 2020 22:28:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 45D8520738 for ; Tue, 18 Aug 2020 22:28:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="M2wOo2Q1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726953AbgHRW2v (ORCPT ); Tue, 18 Aug 2020 18:28:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726904AbgHRW2q (ORCPT ); Tue, 18 Aug 2020 18:28:46 -0400 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 799F9C061389 for ; Tue, 18 Aug 2020 15:28:46 -0700 (PDT) Received: by mail-pf1-x432.google.com with SMTP id m8so10669719pfh.3 for ; Tue, 18 Aug 2020 15:28:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qgBeGmDbDsXKMizmuz8IVmUgWVZ/TZRiqFyy/OXxz8s=; b=M2wOo2Q1mHEjVvDao3EM++9NBpBWmrrZUIMjULjk+35MUpnSKr14BDNguoviJvQYSy 5uEWwJGsLLs0HayNA5kAF5rL+/XCMlkpHbH777ZLE/JVSRhIo/XgVgoFRqAdiTxFD6Sd yhwyim8Ch0ToWrDbGzPf7Cw8V5V/UgK5jY8wM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qgBeGmDbDsXKMizmuz8IVmUgWVZ/TZRiqFyy/OXxz8s=; b=GKIcIeyW/eRn5QXjyf+gtf0TBTEFBZrLETHNSovuClFzNc7Ie7NthvxIMrz+nLtKje /0yhh27+r9PlRCo+OOooQQW73hZcCg6CSzMUqfZeNG03OTc3ECbTtN16bmycH4gPzVoU se/5GM7ZVE+zorP3n7qm5HPsIeefcTM+lw4WycSYnV/cCBYOavG1S4HJkeHwCpOb111L aUHLnUZppYuYdohmN49JL728DRyyomXNrbRcjEf5mNOdzzlqCdg80cOwbO8atEw19e5N 9abQvm5ESXqcM+piWGVVvHop3IbOUl43VgyVzzUc5/ZQDtZsCKAvmwRmmVsdKONAj2YA DMRw== X-Gm-Message-State: AOAM533Dcqt6ZzGas0IEle8spJ7tG1fWUkaweM7DyH/NV04gpBK8FIOS HzcUQgB3l9hYmhJBgsrWmrHIcJJ9wxvq2w== X-Google-Smtp-Source: ABdhPJyXIihR3jry8GPU/Zkk/ryEnuWI+RtmMjoc6tOzdYztyvKKOytYOnbyK7g2TILNNr08PbrhDg== X-Received: by 2002:aa7:8a4d:: with SMTP id n13mr17726102pfa.143.1597789725595; Tue, 18 Aug 2020 15:28:45 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.28.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:28:44 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v1 3/7] adv_monitor: Implement RegisterMonitor() Date: Tue, 18 Aug 2020 15:26:39 -0700 Message-Id: <20200818152612.BlueZ.v1.3.I19ff9cdbd40fe453db0e81aec8bf94dd9490dce3@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This implements the RegisterMonitor() method handler of ADV monitor manager interface. The following tests were performed. - Issue a RegisterMonitor() call with a valid path and expect a success as return. - Issue a RegisterMonitor() call with an invalid path and expect org.bluez.Error.InvalidArguments as return. - Issue two Registermonitor() calls with the same path and expect org.bluez.Error.AlreadyExists. - Verify the values of the registered paths with logging. - Verify D-Bus disconnection callback was triggered when the client detach from D-Bus. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik Reviewed-by: Abhishek Pandit-Subedi --- src/adv_monitor.c | 167 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 4d02237e8..3d27ad18b 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -22,7 +22,9 @@ #endif #define _GNU_SOURCE +#include #include +#include #include #include @@ -34,7 +36,9 @@ #include "adapter.h" #include "dbus-common.h" #include "log.h" +#include "src/error.h" #include "src/shared/mgmt.h" +#include "src/shared/queue.h" #include "src/shared/util.h" #include "adv_monitor.h" @@ -52,12 +56,170 @@ struct btd_adv_monitor_manager { uint16_t max_num_monitors; uint8_t max_num_patterns; + struct queue *apps; /* apps who registered for Adv monitoring */ }; +struct adv_monitor_app { + struct btd_adv_monitor_manager *manager; + char *owner; + char *path; + + DBusMessage *reg; + GDBusClient *client; +}; + +struct app_match_data { + const char *owner; + const char *path; +}; + +/* Replies to an app's D-Bus message and unref it */ +static void app_reply_msg(struct adv_monitor_app *app, DBusMessage *reply) +{ + if (!app || !app->reg || !reply) + return; + + g_dbus_send_message(btd_get_dbus_connection(), reply); + dbus_message_unref(app->reg); + app->reg = NULL; +} + +/* Destroys an app object along with related D-Bus handlers */ +static void app_destroy(void *data) +{ + struct adv_monitor_app *app = data; + + if (!app) + return; + + DBG("Destroy Adv Monitor app %s at path %s", app->owner, app->path); + + if (app->reg) { + app_reply_msg(app, btd_error_failed(app->reg, + "Adv Monitor app destroyed")); + } + + if (app->client) { + g_dbus_client_set_disconnect_watch(app->client, NULL, NULL); + g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL, + NULL); + g_dbus_client_set_ready_watch(app->client, NULL, NULL); + g_dbus_client_unref(app->client); + app->client = NULL; + } + + g_free(app->owner); + app->owner = NULL; + g_free(app->path); + app->path = NULL; + + g_free(app); +} + +/* Handles a D-Bus disconnection event of an app */ +static void app_disconnect_cb(DBusConnection *conn, void *user_data) +{ + struct adv_monitor_app *app = user_data; + + btd_info(app->manager->adapter_id, "Adv Monitor app %s disconnected " + "from D-Bus", app->owner); + if (app && queue_remove(app->manager->apps, app)) + app_destroy(app); +} + +/* Creates an app object, initiates it and sets D-Bus event handlers */ +static struct adv_monitor_app *app_create(DBusConnection *conn, + const char *sender, const char *path, + struct btd_adv_monitor_manager *manager) +{ + struct adv_monitor_app *app; + + if (!path || !sender || !manager) + return NULL; + + app = g_new0(struct adv_monitor_app, 1); + if (!app) + return NULL; + + app->owner = g_strdup(sender); + app->path = g_strdup(path); + app->manager = manager; + app->reg = NULL; + + app->client = g_dbus_client_new(conn, sender, path); + if (!app->client) { + app_destroy(app); + return NULL; + } + + g_dbus_client_set_disconnect_watch(app->client, app_disconnect_cb, app); + g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL, NULL); + g_dbus_client_set_ready_watch(app->client, NULL, NULL); + + return app; +} + +/* Matches an app based on its owner and path */ +static bool app_match(const void *a, const void *b) +{ + const struct adv_monitor_app *app = a; + const struct app_match_data *match = b; + + if (match->owner && strcmp(app->owner, match->owner)) + return false; + + if (match->path && strcmp(app->path, match->path)) + return false; + + return true; +} + +/* Handles a RegisterMonitor D-Bus call */ +static DBusMessage *register_monitor(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + DBusMessageIter args; + struct app_match_data match; + struct adv_monitor_app *app; + struct btd_adv_monitor_manager *manager = user_data; + + if (!dbus_message_iter_init(msg, &args)) + return btd_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) + return btd_error_invalid_args(msg); + + dbus_message_iter_get_basic(&args, &match.path); + + if (!strlen(match.path) || !g_str_has_prefix(match.path, "/")) + return btd_error_invalid_args(msg); + + match.owner = dbus_message_get_sender(msg); + + if (queue_find(manager->apps, app_match, &match)) + return btd_error_already_exists(msg); + + app = app_create(conn, match.owner, match.path, manager); + if (!app) { + btd_error(manager->adapter_id, + "Failed to reserve %s for Adv Monitor app %s", + match.path, match.owner); + return btd_error_failed(msg, + "Failed to create Adv Monitor app"); + } + + queue_push_tail(manager->apps, app); + + btd_info(manager->adapter_id, "Path %s reserved for Adv Monitor app %s", + match.path, match.owner); + + return dbus_message_new_method_return(msg); +} + static const GDBusMethodTable adv_monitor_methods[] = { { GDBUS_METHOD("RegisterMonitor", GDBUS_ARGS({ "application", "o" }), - NULL, NULL) }, + NULL, register_monitor) }, { GDBUS_ASYNC_METHOD("UnregisterMonitor", GDBUS_ARGS({ "application", "o" }), NULL, NULL) }, @@ -157,6 +319,7 @@ static struct btd_adv_monitor_manager *manager_new( manager->mgmt = mgmt_ref(mgmt); manager->adapter_id = btd_adapter_get_index(adapter); manager->path = g_strdup(adapter_get_path(manager->adapter)); + manager->apps = queue_new(); return manager; } @@ -170,6 +333,8 @@ static void manager_free(struct btd_adv_monitor_manager *manager) g_free(manager->path); manager->path = NULL; + queue_destroy(manager->apps, app_destroy); + g_free(manager); } From patchwork Tue Aug 18 22:26:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722259 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A5E26913 for ; Tue, 18 Aug 2020 22:29:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8E86F20786 for ; Tue, 18 Aug 2020 22:29:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="MDyr+hTK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726863AbgHRW3G (ORCPT ); Tue, 18 Aug 2020 18:29:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726539AbgHRW3F (ORCPT ); Tue, 18 Aug 2020 18:29:05 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31521C061389 for ; Tue, 18 Aug 2020 15:29:05 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id mw10so185944pjb.2 for ; Tue, 18 Aug 2020 15:29:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9kYl3apIlbG/g27MOuyrarzuC+I9/z+Glt//16VTKr8=; b=MDyr+hTKeHX+9bEbrFKqHv14MGjhH8fCV6ff+VCyP7KRYFehLvnlCcrSxQ5lWSUaEX hOBxlSUwQsx9glNzrysXWaOqjwxMTJv6UYml4Q0LZaehFcQx7SzxzmpkfDPNaKhFUi8C HB9L9Rs+yMU4AA7xFY5r5mL0KPFyO6FubWE3c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9kYl3apIlbG/g27MOuyrarzuC+I9/z+Glt//16VTKr8=; b=rYkmiCFXKyUvz1Vo2m4vzkEm0Yx89UouQm60ZbDDquH8JwO+ZU4R5HNeG00RnSZLSN ngnOOZm5NhUZpW943KV6idirC3TNhuGsick/tI9lijm8+1r4u0AJLt04vgA09fPqczV+ hlh/dn9O2c/fGjaQpWXdnyFh908P3zURQEdLQnxPsfIyOmOJo2HE8tpvBjnORcx0Bxy6 z+h6D/pyaJdIWvnhlEZ4TP22BYpQvZgaawE24zf4tdHA3PgJtSS1xDHJq+UD51nRyg0z XPMwMMQpohFzN/kdyw1smfTg8hUp6GaxbGqWcDpaCZejcHq9SehGi6Ly/Pqy4K/JuUdT muQQ== X-Gm-Message-State: AOAM530AoZ04qIUf166aEXV3GlM93UBTA8URtf89Vd3Q9+0GcOWJFKtq noUYfGyW3PeHfb1+A3I7HA5cNcpxmkOhxA== X-Google-Smtp-Source: ABdhPJxfO/DzC94MBjdQi5OaizMKSZfBmvdk2rjDc/in+NWXkACuuiVmURd7wCY4E/KQvwKn4cWI5w== X-Received: by 2002:a17:902:d907:: with SMTP id c7mr17367789plz.132.1597789744345; Tue, 18 Aug 2020 15:29:04 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.29.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:29:03 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v1 4/7] adv_monitor: Implement UnregisterMonitor() Date: Tue, 18 Aug 2020 15:26:41 -0700 Message-Id: <20200818152612.BlueZ.v1.4.I335e42ab9a238261c2492c308ce77c959f631483@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This implements the UnregisterMonitor() method handler of ADV monitor manager interface. The following tests were performed. - Issue a UnregisterMonitor() call with a nonexistent path and expect org.bluez.Error.DoesNotExist as the return. - Issue a UnregisterMonitor() call with a invalid path and expect org.bluez.Error.InvalidArguments as the return. - Issue RegisterMonitor() with a path, issue UnregisterMonitor() and expect a successful method call return. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik Reviewed-by: Abhishek Pandit-Subedi --- src/adv_monitor.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 3d27ad18b..a9e2e4421 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -216,13 +216,48 @@ static DBusMessage *register_monitor(DBusConnection *conn, DBusMessage *msg, return dbus_message_new_method_return(msg); } +/* Handles UnregisterMonitor D-Bus call */ +static DBusMessage *unregister_monitor(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + DBusMessageIter args; + struct app_match_data match; + struct adv_monitor_app *app; + struct btd_adv_monitor_manager *manager = user_data; + + if (!dbus_message_iter_init(msg, &args)) + return btd_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) + return btd_error_invalid_args(msg); + + dbus_message_iter_get_basic(&args, &match.path); + + if (!strlen(match.path) || !g_str_has_prefix(match.path, "/")) + return btd_error_invalid_args(msg); + + match.owner = dbus_message_get_sender(msg); + + app = queue_find(manager->apps, app_match, &match); + if (!app) + return btd_error_does_not_exist(msg); + + queue_remove(manager->apps, app); + app_destroy(app); + + btd_info(manager->adapter_id, "Path %s removed along with Adv Monitor " + "app %s", match.path, match.owner); + + return dbus_message_new_method_return(msg); +} + static const GDBusMethodTable adv_monitor_methods[] = { { GDBUS_METHOD("RegisterMonitor", GDBUS_ARGS({ "application", "o" }), NULL, register_monitor) }, { GDBUS_ASYNC_METHOD("UnregisterMonitor", GDBUS_ARGS({ "application", "o" }), - NULL, NULL) }, + NULL, unregister_monitor) }, { } }; From patchwork Tue Aug 18 22:26:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722261 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B59661575 for ; Tue, 18 Aug 2020 22:29:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C69220738 for ; Tue, 18 Aug 2020 22:29:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ELIDr4kP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726967AbgHRW31 (ORCPT ); Tue, 18 Aug 2020 18:29:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42674 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726539AbgHRW30 (ORCPT ); Tue, 18 Aug 2020 18:29:26 -0400 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7DF4C061389 for ; Tue, 18 Aug 2020 15:29:26 -0700 (PDT) Received: by mail-pl1-x62b.google.com with SMTP id t11so9882448plr.5 for ; Tue, 18 Aug 2020 15:29:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yuBC8ZYcilKT59d9GC2Zo6Yq4NAlJg5iM805qukCu2s=; b=ELIDr4kP+wC9QUKYuBrn4Uv9W0qWVVTjpIAbhWFRCxbM1Rzw1l3zgcB+jJ1Yg9c+op f6lQ5tRevzAfySjEBosnwkepZcekz8FhkxKHwg8NXoEQSPz3y5vfrq7mfWJ1ptjUvi28 gbhCQYEgePQXR+DCG1vBEBMoQP/rLZgIEX2Rk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yuBC8ZYcilKT59d9GC2Zo6Yq4NAlJg5iM805qukCu2s=; b=aYh3NOPLolkEnYmQKc1ZisSae0idSuug+RXAyIXhFe5iLADi32zE9xoQU/8A5sC5db tEpFngZOdScpZkffYGeG4dFdGSh4JlVoFz7Hb5g1dZSanO5lxkPAXC99jX/q94tCI1n1 3xk1Un6FcDtNh8/ux1Zh1kinnkCBVtVolWE4SNjKhtl0kiMk7q0f+q3IFayUtf0v+L+n zXxh0Sj+Gqgd/UF1YO6sOE++HApYqF7oRtTIIPHAb0W8OXBhCGjdmNko9/gQwJavnAYG jO60iD9kRWDVY+gxREPV9getmsdGg6Ip7YrXTO+0p3Wwc4Z5bzK1KsTx0DEGxmXVsaik Mk1g== X-Gm-Message-State: AOAM530k6K/Oy23WjO0avW88sMKx07IQhW0kr+2dVMQMWO/K5+20N7ld UBvSGSLSzESirXRbl8wi4QQh0mfccGxbEQ== X-Google-Smtp-Source: ABdhPJy0JTvg8ebWc+NNgtHD6tFUL7FJCCV+DjlzbKHgJBvw40rWOGYsX3K1uZslyeBpYhaS7ek1Zw== X-Received: by 2002:a17:902:43:: with SMTP id 61mr17599611pla.16.1597789764912; Tue, 18 Aug 2020 15:29:24 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.29.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:29:23 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou Subject: [BlueZ PATCH v1 5/7] adv_monitor: Handle D-Bus client ready events Date: Tue, 18 Aug 2020 15:26:43 -0700 Message-Id: <20200818152612.BlueZ.v1.5.Id5b1ced1530cb21559bc1dcf29d8764b0c7df825@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds a handler of client ready events. The handler replies to the RegisterMonitor() method call. The following tests were performed. - Call RegisterMonitor() and expect to receive a return. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik --- src/adv_monitor.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index a9e2e4421..b5ea5ee99 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -127,9 +127,22 @@ static void app_disconnect_cb(DBusConnection *conn, void *user_data) app_destroy(app); } +/* Handles the ready signal of Adv Monitor app */ +static void app_ready_cb(GDBusClient *client, void *user_data) +{ + struct adv_monitor_app *app = user_data; + uint16_t adapter_id = app->manager->adapter_id; + + btd_info(adapter_id, "Path %s reserved for Adv Monitor app %s", + app->path, app->owner); + + app_reply_msg(app, dbus_message_new_method_return(app->reg)); +} + /* Creates an app object, initiates it and sets D-Bus event handlers */ static struct adv_monitor_app *app_create(DBusConnection *conn, - const char *sender, const char *path, + DBusMessage *msg, const char *sender, + const char *path, struct btd_adv_monitor_manager *manager) { struct adv_monitor_app *app; @@ -154,7 +167,9 @@ static struct adv_monitor_app *app_create(DBusConnection *conn, g_dbus_client_set_disconnect_watch(app->client, app_disconnect_cb, app); g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL, NULL); - g_dbus_client_set_ready_watch(app->client, NULL, NULL); + g_dbus_client_set_ready_watch(app->client, app_ready_cb, app); + + app->reg = dbus_message_ref(msg); return app; } @@ -199,7 +214,7 @@ static DBusMessage *register_monitor(DBusConnection *conn, DBusMessage *msg, if (queue_find(manager->apps, app_match, &match)) return btd_error_already_exists(msg); - app = app_create(conn, match.owner, match.path, manager); + app = app_create(conn, msg, match.owner, match.path, manager); if (!app) { btd_error(manager->adapter_id, "Failed to reserve %s for Adv Monitor app %s", @@ -210,10 +225,7 @@ static DBusMessage *register_monitor(DBusConnection *conn, DBusMessage *msg, queue_push_tail(manager->apps, app); - btd_info(manager->adapter_id, "Path %s reserved for Adv Monitor app %s", - match.path, match.owner); - - return dbus_message_new_method_return(msg); + return NULL; } /* Handles UnregisterMonitor D-Bus call */ @@ -252,7 +264,7 @@ static DBusMessage *unregister_monitor(DBusConnection *conn, } static const GDBusMethodTable adv_monitor_methods[] = { - { GDBUS_METHOD("RegisterMonitor", + { GDBUS_ASYNC_METHOD("RegisterMonitor", GDBUS_ARGS({ "application", "o" }), NULL, register_monitor) }, { GDBUS_ASYNC_METHOD("UnregisterMonitor", From patchwork Tue Aug 18 22:26:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722263 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E2E8A1575 for ; Tue, 18 Aug 2020 22:29:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BF13A20738 for ; Tue, 18 Aug 2020 22:29:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="nJt0hpSb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726953AbgHRW3v (ORCPT ); Tue, 18 Aug 2020 18:29:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42736 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726539AbgHRW3v (ORCPT ); Tue, 18 Aug 2020 18:29:51 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA125C061389 for ; Tue, 18 Aug 2020 15:29:50 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id v16so278736plo.1 for ; Tue, 18 Aug 2020 15:29:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YT0YyTUY4S26P5kQiqn3Ul4KARkxUh8IUNOUtiUr9Us=; b=nJt0hpSbwgTyd3FHCAWy/ueQC0EV/RG0DBiG9AHhtYVwvbEbkN62dV5WM6vahO6n0Q 1F52CgaY3B+Sc7CfyH/uzOg+LNhekio925wQHK9hpjqy2JXFzY01CK6o8Stjd4X9OnQT aCs4ZY3IOwDl2+ldD61V63IVCI+/RD+/UZlPM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YT0YyTUY4S26P5kQiqn3Ul4KARkxUh8IUNOUtiUr9Us=; b=fe5i/blEDQLTIvmYqBjg1S9lbB7Yp7FelhoZWJbItLiOW9tmM+Of6wegrID4Y6MIEm PS5cupk/NnyigZlJrWEvYg52pUfoKPJk7ajMcUXD7BN5JgxDzj7mU/d5FihsMcV3U588 BPivmCppI35sepVFA6BS9LNhwx4TfL5F7deBCImr+g1V2z0uJKPgZX+lWPNcPycVoqal l2i8gFCuc+k6K2ec811Sa/HhrCX94ue9hYGQ2NrWKi9qbzVnndit+/G9tvCzeFYvghdQ nZBH1s3gnmh5eyIAC/7BZgKnwS2D6abAx2oQ2vGPe0xPp0K4+HHK+jvLtbtvJYcfUsLS /nBg== X-Gm-Message-State: AOAM5330fvwSoDmyRCU7QHA7A4nRH0iLVrvLgbDazaFupVh2J92kOSbI 9rCoeIHhXq7IfGIew5ICR48BGKto0JQkDQ== X-Google-Smtp-Source: ABdhPJyxhgu+gTIUE7ra1Fqyg/umHyBYbD521G3Fj2EAqEYrMT34HWAfH0rQGfFibujr5qjx4dt0HQ== X-Received: by 2002:a17:90a:ce97:: with SMTP id g23mr1719735pju.216.1597789788347; Tue, 18 Aug 2020 15:29:48 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.29.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:29:47 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou Subject: [BlueZ PATCH v1 6/7] adv_monitor: Handle D-Bus proxy event of an ADV monitor Date: Tue, 18 Aug 2020 15:26:45 -0700 Message-Id: <20200818152612.BlueZ.v1.6.I47744c7eef31f44cf393dea2b3e437d7b41cef79@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds two handlers, one for adding and one for removing, of D-Bus proxy events. The handler of property changes is set to NULL as intended, since for simplicity no further changes on monitor's properties would affect the ongoing monitoring. The following test steps were performed with bluetoothctl. - After registering the root path, expose two monitors and verify that the proxy added event are received. - Have two monitors added, unexpose the monitors, and verify that the proxy removed events are received for those two monitors. - Have two monitors added, unregister the monitors and verify that the proxy removed events are received for those two monitors. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik --- src/adv_monitor.c | 492 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 479 insertions(+), 13 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index b5ea5ee99..23fbc2b45 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -37,14 +37,23 @@ #include "dbus-common.h" #include "log.h" #include "src/error.h" +#include "src/shared/ad.h" #include "src/shared/mgmt.h" #include "src/shared/queue.h" #include "src/shared/util.h" #include "adv_monitor.h" +#define ADV_MONITOR_INTERFACE "org.bluez.AdvertisementMonitor1" #define ADV_MONITOR_MGR_INTERFACE "org.bluez.AdvertisementMonitorManager1" +#define ADV_MONITOR_UNSET_RSSI 127 /* dBm */ +#define ADV_MONITOR_MAX_RSSI 20 /* dBm */ +#define ADV_MONITOR_MIN_RSSI -127 /* dBm */ +#define ADV_MONITOR_UNSET_TIMER 0 /* second */ +#define ADV_MONITOR_MIN_TIMER 1 /* second */ +#define ADV_MONITOR_MAX_TIMER 300 /* second */ + struct btd_adv_monitor_manager { struct btd_adapter *adapter; struct mgmt *mgmt; @@ -66,6 +75,43 @@ struct adv_monitor_app { DBusMessage *reg; GDBusClient *client; + + struct queue *monitors; +}; + +enum monitor_type { + MONITOR_TYPE_NONE, + MONITOR_TYPE_OR_PATTERNS, +}; + +enum monitor_state { + MONITOR_STATE_NEW, /* New but not yet init'ed with actual values */ + MONITOR_STATE_FAILED, /* Failed to be init'ed */ + MONITOR_STATE_INITED, /* Init'ed but not yet sent to kernel */ + MONITOR_STATE_HONORED, /* Accepted by kernel */ +}; + +struct pattern { + uint8_t ad_type; + uint8_t offset; + uint8_t length; + uint8_t value[BT_AD_MAX_DATA_LEN]; +}; + +struct adv_monitor { + struct adv_monitor_app *app; + GDBusProxy *proxy; + char *path; + + enum monitor_state state; /* MONITOR_STATE_* */ + + int8_t high_rssi; /* high RSSI threshold */ + uint16_t high_rssi_timeout; /* high RSSI threshold timeout */ + int8_t low_rssi; /* low RSSI threshold */ + uint16_t low_rssi_timeout; /* low RSSI threshold timeout */ + + enum monitor_type type; /* MONITOR_TYPE_* */ + struct queue *patterns; }; struct app_match_data { @@ -73,6 +119,14 @@ struct app_match_data { const char *path; }; +const struct adv_monitor_type { + enum monitor_type type; + const char *name; +} supported_types[] = { + { MONITOR_TYPE_OR_PATTERNS, "or_patterns" }, + { }, +}; + /* Replies to an app's D-Bus message and unref it */ static void app_reply_msg(struct adv_monitor_app *app, DBusMessage *reply) { @@ -84,6 +138,52 @@ static void app_reply_msg(struct adv_monitor_app *app, DBusMessage *reply) app->reg = NULL; } +/* Frees a pattern */ +static void pattern_free(void *data) +{ + struct pattern *pattern = data; + + if (!pattern) + return; + + g_free(pattern); +} + +/* Frees a monitor object */ +static void monitor_free(void *data) +{ + struct adv_monitor *monitor = data; + + if (!monitor) + return; + + monitor->app = NULL; + g_dbus_proxy_unref(monitor->proxy); + monitor->proxy = NULL; + g_free(monitor->path); + monitor->path = NULL; + + queue_destroy(monitor->patterns, pattern_free); + monitor->patterns = NULL; + + g_free(monitor); +} + +/* Calls Release() method of the remote Adv Monitor */ +static void monitor_release(void *data, void *user_data) +{ + struct adv_monitor *monitor = data; + + if (!monitor) + return; + + DBG("Calling Release() on Adv Monitor of owner %s at path %s", + monitor->app->owner, monitor->path); + + g_dbus_proxy_method_call(monitor->proxy, "Release", NULL, NULL, NULL, + NULL); +} + /* Destroys an app object along with related D-Bus handlers */ static void app_destroy(void *data) { @@ -94,6 +194,9 @@ static void app_destroy(void *data) DBG("Destroy Adv Monitor app %s at path %s", app->owner, app->path); + queue_foreach(app->monitors, monitor_release, NULL); + queue_destroy(app->monitors, monitor_free); + if (app->reg) { app_reply_msg(app, btd_error_failed(app->reg, "Adv Monitor app destroyed")); @@ -139,6 +242,372 @@ static void app_ready_cb(GDBusClient *client, void *user_data) app_reply_msg(app, dbus_message_new_method_return(app->reg)); } +/* Allocates an Adv Monitor */ +static struct adv_monitor *monitor_new(struct adv_monitor_app *app, + GDBusProxy *proxy) +{ + struct adv_monitor *monitor; + + if (!app || !proxy) + return NULL; + + monitor = g_new0(struct adv_monitor, 1); + if (!monitor) + return NULL; + + monitor->app = app; + monitor->proxy = g_dbus_proxy_ref(proxy); + monitor->path = g_strdup(g_dbus_proxy_get_path(proxy)); + + monitor->state = MONITOR_STATE_NEW; + + monitor->high_rssi = ADV_MONITOR_UNSET_RSSI; + monitor->high_rssi_timeout = ADV_MONITOR_UNSET_TIMER; + monitor->low_rssi = ADV_MONITOR_UNSET_RSSI; + monitor->low_rssi_timeout = ADV_MONITOR_UNSET_TIMER; + + monitor->type = MONITOR_TYPE_NONE; + monitor->patterns = NULL; + + return monitor; +} + +/* Matches a monitor based on its D-Bus path */ +static bool monitor_match(const void *a, const void *b) +{ + const GDBusProxy *proxy = b; + const struct adv_monitor *monitor = a; + + if (!proxy || !monitor) + return false; + + if (strcmp(g_dbus_proxy_get_path(proxy), monitor->path) != 0) + return false; + + return true; +} + +/* Retrieves Type from the remote Adv Monitor object, verifies the value and + * update the local Adv Monitor + */ +static bool parse_monitor_type(struct adv_monitor *monitor, const char *path) +{ + DBusMessageIter iter; + const struct adv_monitor_type *t; + const char *type_str; + uint16_t adapter_id = monitor->app->manager->adapter_id; + + if (!g_dbus_proxy_get_property(monitor->proxy, "Type", &iter)) { + btd_error(adapter_id, "Failed to retrieve property Type from " + "the Adv Monitor at path %s", path); + return false; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + goto failed; + + dbus_message_iter_get_basic(&iter, &type_str); + + for (t = supported_types; t->name; t++) { + if (strcmp(t->name, type_str) == 0) { + monitor->type = t->type; + return true; + } + } + +failed: + btd_error(adapter_id, "Invalid argument of property Type of the Adv " + "Monitor at path %s", path); + + return false; +} + +/* Retrieves RSSIThresholdsAndTimers from the remote Adv Monitor object, + * verifies the values and update the local Adv Monitor + */ +static bool parse_rssi_and_timeout(struct adv_monitor *monitor, + const char *path) +{ + DBusMessageIter prop_struct, iter; + int16_t h_rssi, l_rssi; + uint16_t h_rssi_timer, l_rssi_timer; + uint16_t adapter_id = monitor->app->manager->adapter_id; + + /* Property RSSIThresholdsAndTimers is optional */ + if (!g_dbus_proxy_get_property(monitor->proxy, + "RSSIThresholdsAndTimers", + &prop_struct)) { + DBG("Adv Monitor at path %s provides no RSSI thresholds and " + "timeouts", path); + return true; + } + + if (dbus_message_iter_get_arg_type(&prop_struct) != DBUS_TYPE_STRUCT) + goto failed; + + dbus_message_iter_recurse(&prop_struct, &iter); + + /* Extract HighRSSIThreshold */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT16) + goto failed; + dbus_message_iter_get_basic(&iter, &h_rssi); + if (!dbus_message_iter_next(&iter)) + goto failed; + + /* Extract HighRSSIThresholdTimer */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16) + goto failed; + dbus_message_iter_get_basic(&iter, &h_rssi_timer); + if (!dbus_message_iter_next(&iter)) + goto failed; + + /* Extract LowRSSIThreshold */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT16) + goto failed; + dbus_message_iter_get_basic(&iter, &l_rssi); + if (!dbus_message_iter_next(&iter)) + goto failed; + + /* Extract LowRSSIThresholdTimer */ + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16) + goto failed; + dbus_message_iter_get_basic(&iter, &l_rssi_timer); + + /* Verify the values of RSSIs and their timers. For simplicity, we + * enforce the all-or-none rule to these fields. In other words, either + * all are set to the unset values or all are set within valid ranges. + */ + if (h_rssi == ADV_MONITOR_UNSET_RSSI && + l_rssi == ADV_MONITOR_UNSET_RSSI && + h_rssi_timer == ADV_MONITOR_UNSET_TIMER && + l_rssi_timer == ADV_MONITOR_UNSET_TIMER) { + goto done; + } + + if (h_rssi < ADV_MONITOR_MIN_RSSI || h_rssi > ADV_MONITOR_MAX_RSSI || + l_rssi < ADV_MONITOR_MIN_RSSI || + l_rssi > ADV_MONITOR_MAX_RSSI || h_rssi <= l_rssi) { + goto failed; + } + + if (h_rssi_timer < ADV_MONITOR_MIN_TIMER || + h_rssi_timer > ADV_MONITOR_MAX_TIMER || + l_rssi_timer < ADV_MONITOR_MIN_TIMER || + l_rssi_timer > ADV_MONITOR_MAX_TIMER) { + goto failed; + } + + monitor->high_rssi = h_rssi; + monitor->low_rssi = l_rssi; + monitor->high_rssi_timeout = h_rssi_timer; + monitor->low_rssi_timeout = l_rssi_timer; + +done: + DBG("Adv Monitor at %s initiated with high RSSI threshold %d, high " + "RSSI threshold timeout %d, low RSSI threshold %d, low RSSI " + "threshold timeout %d", path, monitor->high_rssi, + monitor->high_rssi_timeout, monitor->low_rssi, + monitor->low_rssi_timeout); + + return true; + +failed: + monitor->high_rssi = ADV_MONITOR_UNSET_RSSI; + monitor->low_rssi = ADV_MONITOR_UNSET_RSSI; + monitor->high_rssi_timeout = ADV_MONITOR_UNSET_TIMER; + monitor->low_rssi_timeout = ADV_MONITOR_UNSET_TIMER; + + btd_error(adapter_id, "Invalid argument of property " + "RSSIThresholdsAndTimers of the Adv Monitor at path %s", + path); + + return false; +} + +/* Retrieves Patterns from the remote Adv Monitor object, verifies the values + * and update the local Adv Monitor + */ +static bool parse_patterns(struct adv_monitor *monitor, const char *path) +{ + DBusMessageIter array, array_iter; + uint16_t num_patterns = 0; + uint16_t adapter_id = monitor->app->manager->adapter_id; + + if (!g_dbus_proxy_get_property(monitor->proxy, "Patterns", &array)) { + btd_error(adapter_id, "Failed to retrieve property Patterns " + "from the Adv Monitor at path %s", path); + return false; + } + + monitor->patterns = queue_new(); + + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&array) != + DBUS_TYPE_STRUCT) { + goto failed; + } + + dbus_message_iter_recurse(&array, &array_iter); + + while (dbus_message_iter_get_arg_type(&array_iter) == + DBUS_TYPE_STRUCT) { + int value_len; + uint8_t *value; + uint8_t offset, ad_type; + struct pattern *pattern; + DBusMessageIter struct_iter, value_iter; + + dbus_message_iter_recurse(&array_iter, &struct_iter); + + // Extract start position + if (dbus_message_iter_get_arg_type(&struct_iter) != + DBUS_TYPE_BYTE) { + goto failed; + } + dbus_message_iter_get_basic(&struct_iter, &offset); + if (!dbus_message_iter_next(&struct_iter)) + goto failed; + + // Extract AD data type + if (dbus_message_iter_get_arg_type(&struct_iter) != + DBUS_TYPE_BYTE) { + goto failed; + } + dbus_message_iter_get_basic(&struct_iter, &ad_type); + if (!dbus_message_iter_next(&struct_iter)) + goto failed; + + // Extract value of a pattern + if (dbus_message_iter_get_arg_type(&struct_iter) != + DBUS_TYPE_ARRAY) { + goto failed; + } + dbus_message_iter_recurse(&struct_iter, &value_iter); + dbus_message_iter_get_fixed_array(&value_iter, &value, + &value_len); + + // Verify the values + if (offset > BT_AD_MAX_DATA_LEN - 1) + goto failed; + + if (ad_type > BT_AD_3D_INFO_DATA && + ad_type != BT_AD_MANUFACTURER_DATA + || ad_type < BT_AD_FLAGS) { + goto failed; + } + + if (!value || value_len <= 0 || value_len > BT_AD_MAX_DATA_LEN) + goto failed; + + pattern = g_new0(struct pattern, 1); + if (!pattern) + goto failed; + + pattern->ad_type = ad_type; + pattern->offset = offset; + pattern->length = value_len; + g_memmove(pattern->value, value, pattern->length); + + queue_push_tail(monitor->patterns, pattern); + + dbus_message_iter_next(&array_iter); + } + + /* There must be at least one pattern. */ + if (queue_isempty(monitor->patterns)) + goto failed; + + return true; + +failed: + queue_destroy(monitor->patterns, pattern_free); + monitor->patterns = NULL; + + btd_error(adapter_id, "Invalid argument of property Patterns of the " + "Adv Monitor at path %s", path); + + return false; +} + +/* Processes the content of the remote Adv Monitor */ +static bool monitor_process(struct adv_monitor *monitor, + struct adv_monitor_app *app) +{ + const char *path = g_dbus_proxy_get_path(monitor->proxy); + + monitor->state = MONITOR_STATE_FAILED; + + if (!parse_monitor_type(monitor, path)) + goto done; + + if (!parse_rssi_and_timeout(monitor, path)) + goto done; + + if (monitor->type == MONITOR_TYPE_OR_PATTERNS && + parse_patterns(monitor, path)) { + monitor->state = MONITOR_STATE_INITED; + } + +done: + return monitor->state != MONITOR_STATE_FAILED; +} + +/* Handles an Adv Monitor D-Bus proxy added event */ +static void monitor_proxy_added_cb(GDBusProxy *proxy, void *user_data) +{ + struct adv_monitor *monitor; + struct adv_monitor_app *app = user_data; + uint16_t adapter_id = app->manager->adapter_id; + const char *path = g_dbus_proxy_get_path(proxy); + const char *iface = g_dbus_proxy_get_interface(proxy); + + if (strcmp(iface, ADV_MONITOR_INTERFACE) != 0 || + !g_str_has_prefix(path, app->path)) { + return; + } + + if (queue_find(app->monitors, monitor_match, proxy)) { + btd_error(adapter_id, "Adv Monitor proxy already exists with " + "path %s", path); + return; + } + + monitor = monitor_new(app, proxy); + if (!monitor) { + btd_error(adapter_id, "Failed to allocate an Adv Monitor for " + "the object at %s", path); + return; + } + + if (!monitor_process(monitor, app)) { + monitor_release(monitor, NULL); + monitor_free(monitor); + DBG("Adv Monitor at path %s released due to invalid content", + path); + return; + } + + queue_push_tail(app->monitors, monitor); + + DBG("Adv Monitor allocated for the object at path %s", path); +} + +/* Handles the removal of an Adv Monitor D-Bus proxy */ +static void monitor_proxy_removed_cb(GDBusProxy *proxy, void *user_data) +{ + struct adv_monitor *monitor; + struct adv_monitor_app *app = user_data; + + monitor = queue_remove_if(app->monitors, monitor_match, proxy); + if (monitor) { + DBG("Adv Monitor removed for the object at path %s", + monitor->path); + + /* The object was gone, so we don't need to call Release() */ + monitor_free(monitor); + } +} + /* Creates an app object, initiates it and sets D-Bus event handlers */ static struct adv_monitor_app *app_create(DBusConnection *conn, DBusMessage *msg, const char *sender, @@ -165,8 +634,17 @@ static struct adv_monitor_app *app_create(DBusConnection *conn, return NULL; } + app->monitors = queue_new(); + g_dbus_client_set_disconnect_watch(app->client, app_disconnect_cb, app); - g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL, NULL); + + /* Note that any property changes on a monitor object would not affect + * the content of the corresponding monitor. + */ + g_dbus_client_set_proxy_handlers(app->client, monitor_proxy_added_cb, + monitor_proxy_removed_cb, NULL, + app); + g_dbus_client_set_ready_watch(app->client, app_ready_cb, app); app->reg = dbus_message_ref(msg); @@ -273,18 +751,6 @@ static const GDBusMethodTable adv_monitor_methods[] = { { } }; -enum monitor_type { - MONITOR_TYPE_OR_PATTERNS, -}; - -const struct adv_monitor_type { - enum monitor_type type; - const char *name; -} supported_types[] = { - { MONITOR_TYPE_OR_PATTERNS, "or_patterns" }, - { }, -}; - /* Gets SupportedMonitorTypes property */ static gboolean get_supported_monitor_types(const GDBusPropertyTable *property, DBusMessageIter *iter, From patchwork Tue Aug 18 22:26:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miao-chen Chou X-Patchwork-Id: 11722265 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A1BA1392 for ; Tue, 18 Aug 2020 22:31:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E111420709 for ; Tue, 18 Aug 2020 22:31:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Og4WU3id" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726982AbgHRWbj (ORCPT ); Tue, 18 Aug 2020 18:31:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726766AbgHRWbg (ORCPT ); Tue, 18 Aug 2020 18:31:36 -0400 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C18C3C061389 for ; Tue, 18 Aug 2020 15:31:36 -0700 (PDT) Received: by mail-pf1-x429.google.com with SMTP id d188so10666012pfd.2 for ; Tue, 18 Aug 2020 15:31:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Zlvqf0NUFaWEm48IkgWk2VefD7B2sDw4UkatyR8sS4M=; b=Og4WU3idPrNBah+5oHG6lq3gGErO6ayxnp8JMMw5yJouuau6A6b8eYM1qJt/Cljg4z qwDMW1Lx9mq6pZDx/Z6zbFJrxWYTkEci6KEE24x+0K7aA4aASeQfdKs8x0GAIlBQJg8n dqXcyZphfgWnESFkCn2TnXPyOfDxFer6l3N4E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Zlvqf0NUFaWEm48IkgWk2VefD7B2sDw4UkatyR8sS4M=; b=Ujy6SbqkaaObLyFzyIsV+8n0ThGtzvWSIpADHZcidXakKYFvl4BYQ3EOf/84pqDXub BP4r+3AWXS2kidOYswmZS7wT2NsTdtz4ap7IIykswhAyvPeIX9aSNuEAIxSegrArcm4s F4Zmun2DstKFatzUGZYBpJtOcKna+ZrNMJ1sFv91KtQO92dyCHVUTwpIKSy8I9JafpSG BMfgnDdmnQoK07H71cKrXVv5MpRmkJ0s7J+vPueTuUR/XRdVBiXocjZnVMkqn+tB1CRN efFJoixQzD6Lzcj3jusFBPtvURePcHCYWAgaiXYYW+GfBj8Dzi1/GJ7vQ8qjOWRNl9tv oa9Q== X-Gm-Message-State: AOAM5334PN0fZvnKaIrZPLZTHmFDi53C18REiozGlnWVmGEA64H4depW R9Lp46gKzmRCMQOPKhLU9lJTR6p6m2G6iw== X-Google-Smtp-Source: ABdhPJza4ZBSSzG1cmahVgzR81br3ediWZBIno7IgUWM9sSJsZ9iOBawNuJ6xQ7pzQ8T4RrMvI/B9Q== X-Received: by 2002:a65:6a55:: with SMTP id o21mr2016373pgu.64.1597789895904; Tue, 18 Aug 2020 15:31:35 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id mp3sm14137286pjb.0.2020.08.18.15.31.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2020 15:31:35 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Alain Michaud , Manish Mandlik , Luiz Augusto von Dentz , Howard Chung , Miao-chen Chou Subject: [BlueZ PATCH v1 7/7] doc/advertisement-monitor-api: Update Advertisement Monitor API description Date: Tue, 18 Aug 2020 15:26:47 -0700 Message-Id: <20200818152612.BlueZ.v1.7.Iee7e9d13c78dd02c5b283a203dea11a4a4ffa7cc@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200818152612.BlueZ.v1.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> MIME-Version: 1.0 Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This modifies the following description to Advertisement Monitor API. - Add org.bluez.Error.Failed to RegisterMonitor() method. - Add more description about the usage of RegisterMonitor() and UnregisterMonitor() methods. - Add description about the ranges for the fields in property RSSIThresholdsAndTimers. Reviewed-by: Yun-Hao Chung Reviewed-by: Manish Mandlik --- doc/advertisement-monitor-api.txt | 34 +++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/doc/advertisement-monitor-api.txt b/doc/advertisement-monitor-api.txt index 74adbfae9..e09b6fd25 100644 --- a/doc/advertisement-monitor-api.txt +++ b/doc/advertisement-monitor-api.txt @@ -49,7 +49,7 @@ Properties string Type [read-only] org.bluez.AdvertisementMonitorManager1 for the available options. - (Int16, Uint16, Int16, Uint16) RSSIThreshholdsAndTimers [read-only, optional] + (Int16, Uint16, Int16, Uint16) RSSIThresholdsAndTimers [read-only, optional] This contains HighRSSIThreshold, HighRSSIThresholdTimer, LowRSSIThreshold, LowRSSIThresholdTimer in order. The @@ -66,7 +66,11 @@ Properties string Type [read-only] RSSIs of the received advertisement(s) during LowRSSIThresholdTimer do not reach LowRSSIThreshold. - array{(uint8, uint8, string)} Patterns [read-only, optional] + The valid range of a RSSI is -127 to +20 dBm while 127 + dBm indicates unset. The valid range of a timer is 1 to + 300 seconds while 0 indicates unset. + + array{(uint8, uint8, array{byte})} Patterns [read-only, optional] If Type is set to 0x01, this must exist and has at least one entry in the array. @@ -80,8 +84,9 @@ Properties string Type [read-only] See https://www.bluetooth.com/specifications/ assigned-numbers/generic-access-profile/ for the possible allowed value. - string content_of_pattern - This is the value of the pattern. + array{byte} content_of_pattern + This is the value of the pattern. The maximum + length of the bytes is 31. Advertisement Monitor Manager hierarchy ======================================= @@ -91,20 +96,31 @@ Object path /org/bluez/{hci0,hci1,...} Methods void RegisterMonitor(object application) - This registers a hierarchy of advertisement monitors. + This registers the root path of a hierarchy of + advertisement monitors. The application object path together with the D-Bus system bus connection ID define the identification of the application registering advertisement monitors. + Once a root path is registered by a client via this + method, the client can freely expose/unexpose + advertisement monitors without re-registering the root + path again. After use, the client should call + UnregisterMonitor() method to invalidate the + advertisement monitors. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.AlreadyExists + org.bluez.Error.Failed void UnregisterMonitor(object application) - This unregisters advertisement monitors that have been - previously registered. The object path parameter must - match the same value that has been used on - registration. + This unregisters a hierarchy of advertisement monitors + that has been previously registered. The object path + parameter must match the same value that has been used + on registration. Upon unregistration, the advertisement + monitor(s) should expect to receive Release() method as + the signal that the advertisement monitor(s) has been + deactivated. Possible errors: org.bluez.Error.InvalidArguments org.bluez.Error.DoesNotExist