From patchwork Thu Sep 10 04:35:32 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: 11766539 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 F3CCA618 for ; Thu, 10 Sep 2020 04:36:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF6412075E for ; Thu, 10 Sep 2020 04:36:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Jl+1xnuK" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725887AbgIJEga (ORCPT ); Thu, 10 Sep 2020 00:36:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbgIJEgW (ORCPT ); Thu, 10 Sep 2020 00:36:22 -0400 Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F413EC061573 for ; Wed, 9 Sep 2020 21:36:21 -0700 (PDT) Received: by mail-pl1-x641.google.com with SMTP id j7so296378plk.11 for ; Wed, 09 Sep 2020 21:36:21 -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=5aM6VVrTht1FceKkAVmX0ix4M6IUKIpD0QpYq5ZNVn8=; b=Jl+1xnuKFW9ub7ltdSqSvR119Ahfu3I5FYR9J5jAl227l5CdvWp6wgmJW85rYhhTKb 8Kk3HVXVgO+3aMn4rxrC74RKNczyaYVA7cxb47OyLTR06oaZRKbVeBe0ggVPzto9YWAM csH3A/7zWxlg+Y8yfX7V9TMOvx7+6gL/TbrC0= 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=5aM6VVrTht1FceKkAVmX0ix4M6IUKIpD0QpYq5ZNVn8=; b=jlYMVaGmBamdklp5gvXZghd+Wc3YjNjb+h0vBeqDn+dhf4g/gS26l1PEJzlauL05Rs cUpaUw42r/LbSCVz2/W2+qohRnHzczVq1/bFhHg6cze6UqI2c5HY9oXAt81d/ucXsIHO JlP/QcglMYuXc7uJjM0yVFXUoJPQ7aCVaRt/11jImdNoUm2TCKOXaUDY3ZJK/i0FTQfU rtksQTfzggDpuxhBl/FX5M2SUKkzLiHPCwxArmBytqavACf39HVmwP86PDF30cFqv4f+ od4PVcqL+TrJE3YFdxG8YAp1+PUVN1ubZV8Y1X9OttQS9m5l5rYdVuxIcfs2P7toRp+C qc/Q== X-Gm-Message-State: AOAM533tmqKNddpTeTbFrW9AfPcLrPcIBnl7W8p51Oc3ySpEDDuwTdHf sMC9936lTGEdIDAzD7ypxYv934qm6crqqA== X-Google-Smtp-Source: ABdhPJxoLuV75GFsH3LQk38zdw2SofziWDLx6Mg+4cIgoXx8zIxCYBJ7pVqt2ug4IzEpTZGa7HR+aw== X-Received: by 2002:a17:902:b604:: with SMTP id b4mr3689066pls.120.1599712581112; Wed, 09 Sep 2020 21:36:21 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id y4sm4149820pfq.215.2020.09.09.21.36.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:36:20 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v2 1/7] PRE-UPSTREAM: adv_monitor: Introduce org.bluez.AdvertisementMonitorManager1 interface Date: Wed, 9 Sep 2020 21:35:32 -0700 Message-Id: <20200909213423.BlueZ.v2.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 --- Changes in v2: -Use new0 instead of g_new0 -Remove the reset of manager members -Make methods/property experimental Makefile.am | 3 +- src/adapter.c | 14 +++++ src/adapter.h | 3 + src/adv_monitor.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++ src/adv_monitor.h | 32 ++++++++++ 5 files changed, 199 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 1435e2bd7..de327dc98 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,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..8e7dad8dd --- /dev/null +++ b/src/adv_monitor.c @@ -0,0 +1,148 @@ +/* + * + * 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 "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; + char *path; +}; + +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}, + { } +}; + +/* 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); + 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) +{ + mgmt_unref(manager->mgmt); + free(manager->path); + + 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)) { + 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 Thu Sep 10 04:35:34 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: 11766541 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 7398359D for ; Thu, 10 Sep 2020 04:36:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 513FC2076D for ; Thu, 10 Sep 2020 04:36:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="gXiTUIaN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726215AbgIJEgx (ORCPT ); Thu, 10 Sep 2020 00:36:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbgIJEgr (ORCPT ); Thu, 10 Sep 2020 00:36:47 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48CA6C061573 for ; Wed, 9 Sep 2020 21:36:47 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id g29so3582161pgl.2 for ; Wed, 09 Sep 2020 21:36:47 -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=zLi61UtegLxZoRPn4T9W5e3L/HqdjAdjheNWCNy6w+M=; b=gXiTUIaNvECszPA0axiTD/Ygvahp9PvRXjW6IzWyozubqI72bwXJa3r8+40Hi4lZU2 OR9PXo/SWrt83UyMAANKCN/KTq/e0ARItO1nOFskJbuHM8EGhHivoRQKxQR0c709QW73 cIz6Uj4LYvS5T/9+bentuw7SKVo2318TyY4GQ= 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=zLi61UtegLxZoRPn4T9W5e3L/HqdjAdjheNWCNy6w+M=; b=CafiI0ZcglnMhjFA+Lxru69Z+yKpAuiNr9lV/Zu6gRhqdgXvT1T4RpvkWOl9+YuieR LoJ248p/z6nsi/9YWRhCBfyHbbvuxBipJMVz3f4x1QycrtjqvqGS3Suw4kXUAwZLGuZa rEC+ObGKfgChhpIsiqIOYza4xfPv5Uz7RemFfy5cmDGUeK87e8V53lYFdk97kglX+3QC d03m8YTLdNTbJ+UeJSuwpIrqgqCHhIcJ2GaH8vhZCyBFTuXnthaeT+2+Tw/ayMzI7JhE cD5xRgt6wSJJG2RU9VxHtuEVTiTeB9UKcaJ/ddkkxm4Lp+RCaRy3UD6AIlhNPumkWeAf EKhw== X-Gm-Message-State: AOAM533cMs1RyR4cMR1vCVbDurcRfb3HNXW2elHWNTawC7Ly8vdfGmMR BW0LrM/ygawdKfyJhRqzmyRDBHj1lkrlfw== X-Google-Smtp-Source: ABdhPJwHFrvxsHABu6Z3KByav3ToikQr89a3seZRE8YHFDSaxPPMh+WPVvJxkKhkYZF7VYtoey4TEw== X-Received: by 2002:a62:e40a:0:b029:138:8fd6:7fd5 with SMTP id r10-20020a62e40a0000b02901388fd67fd5mr3754452pfh.1.1599712605364; Wed, 09 Sep 2020 21:36: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 y4sm4149820pfq.215.2020.09.09.21.36.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:36:44 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v2 2/7] PRE-UPSTREAM: adv_monitor: Implement Get functions of Adv monitor manager properties Date: Wed, 9 Sep 2020 21:35:34 -0700 Message-Id: <20200909213423.BlueZ.v2.2.I9960e45d36be3edb5f17de025e7eb8257d3cddef@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- (no changes since v1) src/adv_monitor.c | 128 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 5 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 8e7dad8dd..54e67bf2c 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -28,6 +28,9 @@ #include #include +#include "lib/bluetooth.h" +#include "lib/mgmt.h" + #include "adapter.h" #include "dbus-common.h" #include "log.h" @@ -43,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[] = { @@ -55,10 +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, + {"SupportedMonitorTypes", "as", get_supported_monitor_types, NULL, NULL, G_DBUS_PROPERTY_FLAG_EXPERIMENTAL}, - {"SupportedFeatures", "as", NULL, NULL, NULL}, + {"SupportedFeatures", "as", get_supported_features, NULL, NULL}, { } }; @@ -106,6 +183,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, @@ -129,9 +242,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 Thu Sep 10 04:35:36 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: 11766543 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 1E17C59D for ; Thu, 10 Sep 2020 04:37:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EFCE52076D for ; Thu, 10 Sep 2020 04:37:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Isz5pQRv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726079AbgIJEhM (ORCPT ); Thu, 10 Sep 2020 00:37:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbgIJEhF (ORCPT ); Thu, 10 Sep 2020 00:37:05 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C535BC061573 for ; Wed, 9 Sep 2020 21:37:03 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id c196so4047374pfc.0 for ; Wed, 09 Sep 2020 21:37:03 -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=AJPZOT5B0nuolz+Ul8NKg3I9PVUhFT9btrB6Oqu6yw8=; b=Isz5pQRvhWQj419nYxiGBKgSx6hLqGyxJQqIZFuOVhuOo55ZDuIbD+KRhpCU7wK/gK pRocr2IqvW06GW08EdVjq1g0GefSjO7aLmvbpZ/OkzJ3RJZIN5VETSO71tEeFo6eP6YY 5ql5rPhB7HwC5hErfzLPe9GyJOIU5Z4dzs+D4= 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=AJPZOT5B0nuolz+Ul8NKg3I9PVUhFT9btrB6Oqu6yw8=; b=QOkmakalhfIgplsXB1iUsWhZ9OarZVgmaHh98W6BYD2koQ/reKWX66XCC98JODW+0p wFVcExrsVvmuMJ1w3fy7hBB3MS6jp52WXkUWBRWgN4X5xtdDsULJ9sKhc+d8PY1bcoPF D2kzvTe+hRaEs2TPQnMGNJ6P1V7IRG6fv0IWUzo3hAKm3xrr4ukdr5JUcL8EAFPKGjBM ZCe1euTTXI2StANZAbpgEsiQ/9yz8/ljaxedn9KaIG/BBfzm1+PDgVkspD9t70CSCgHJ 5GmIkWuYy8t/nmDrUYy5uYW3px0+Pg8AY0puNt2lqEZPPOTl0G8nzkARXSbItVr4szNU CFag== X-Gm-Message-State: AOAM531nm8FSPwrJgxsdm/nPbToGSnshPBwCTI4IjRmBnUeGAyUsG03g 8ArjC4R+cNota4uuDdfpDUpvj8ZXeVboAA== X-Google-Smtp-Source: ABdhPJx5FlxjeVUW0iiEp7FboC5Jdy9JvxAjzH3Dhn4g8ErFp+gksu+1oGDJBny29jxO6An80BkEHA== X-Received: by 2002:a63:4e5e:: with SMTP id o30mr2983925pgl.324.1599712622909; Wed, 09 Sep 2020 21:37:02 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id y4sm4149820pfq.215.2020.09.09.21.37.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:37:02 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v2 3/7] PRE-UPSTREAM: adv_monitor: Implement RegisterMonitor() Date: Wed, 9 Sep 2020 21:35:36 -0700 Message-Id: <20200909213423.BlueZ.v2.3.I19ff9cdbd40fe453db0e81aec8bf94dd9490dce3@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- Changes in v2: - Use new0() instead of g_new0() - Remove the reset of app members src/adv_monitor.c | 164 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 54e67bf2c..b8b55d2fc 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,167 @@ 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); + } + + g_free(app->owner); + g_free(app->path); + + 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 = 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_EXPERIMENTAL_METHOD("RegisterMonitor", GDBUS_ARGS({ "application", "o" }), - NULL, NULL) }, + NULL, register_monitor) }, { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterMonitor", GDBUS_ARGS({ "application", "o" }), NULL, NULL) }, @@ -157,6 +316,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; } @@ -167,6 +327,8 @@ static void manager_free(struct btd_adv_monitor_manager *manager) mgmt_unref(manager->mgmt); free(manager->path); + queue_destroy(manager->apps, app_destroy); + free(manager); } From patchwork Thu Sep 10 04:35:38 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: 11766545 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 1D91F59D for ; Thu, 10 Sep 2020 04:37:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 00D3F2078B for ; Thu, 10 Sep 2020 04:37:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="mMZIaj0N" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725913AbgIJEhV (ORCPT ); Thu, 10 Sep 2020 00:37:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbgIJEhQ (ORCPT ); Thu, 10 Sep 2020 00:37:16 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0D00C061573 for ; Wed, 9 Sep 2020 21:37:15 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id k15so3886701pfc.12 for ; Wed, 09 Sep 2020 21:37:15 -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=wgoIVPRWXVNntcbMbldt7TpPEHI4+Eh2hW+gjZOt2Js=; b=mMZIaj0NZ9xEAHaaPZidEIAITW8us9QoZ94vAL+aQsJXbN8IMFMwnlNlzXXsyWr2zO Bj5C6trz+gbSyKL1s7kn+dmBYE/+04JoFwQCc35z1sCd23gaaEtLV3PwRiBjkRZ5BIHS OHqossIt7YsJMSQoau5JQf37NlaFMahOXIURA= 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=wgoIVPRWXVNntcbMbldt7TpPEHI4+Eh2hW+gjZOt2Js=; b=kK/8XIEP+fDmtIqxtJ/ngN3527VI0V/XROrahzBxEHp4QetkYJl5nRL6OPp7zOu0B2 osgp/2acOM1uGrfpEgRCn/nkDmHObsjjb7BYL40L6dkrrhV3HxdIH5hwDdEKwNhZwRya sSjgkjvrAdVc+YwUXuWJn5PIXFSEB3h+dAjgBZ/henJGRJkX+3uf0iPm8jC8jGrzGaVn 75uST6AE7La26h7Iw/e/MZJcOVqTSBsLeLi6h3g6D1/WoWh06OZ1bjYshbFmT2f1KXiU BHtB3RtmJMMbC6HOwb7rFPmm07j/+H/dBmD5oOSUY5nP3vfHSlkv8RoyPZojLtHUWK++ EmRw== X-Gm-Message-State: AOAM530NdoKHzK7v9yCegGBoZRzhMeZObFjzDa7+NRKWYrSAj59Vfc4Q ApTa/Mwj8u+IwLeWfE/R9tA/5iQaICmlhA== X-Google-Smtp-Source: ABdhPJy3jqcGuJmD+yt4DwMgs2oXrRep81aESmkWSzzWikwtlNguSlpyLRrwDmBfhq0qHvF30S0T7A== X-Received: by 2002:a62:3007:0:b029:13c:1611:6526 with SMTP id w7-20020a6230070000b029013c16116526mr3659217pfw.6.1599712635178; Wed, 09 Sep 2020 21:37:15 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id y4sm4149820pfq.215.2020.09.09.21.37.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:37:14 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou , Abhishek Pandit-Subedi Subject: [BlueZ PATCH v2 4/7] PRE-UPSTREAM: adv_monitor: Implement UnregisterMonitor() Date: Wed, 9 Sep 2020 21:35:38 -0700 Message-Id: <20200909213423.BlueZ.v2.4.I335e42ab9a238261c2492c308ce77c959f631483@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- (no changes since v1) 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 b8b55d2fc..1a38e6994 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -213,13 +213,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_EXPERIMENTAL_METHOD("RegisterMonitor", GDBUS_ARGS({ "application", "o" }), NULL, register_monitor) }, { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterMonitor", GDBUS_ARGS({ "application", "o" }), - NULL, NULL) }, + NULL, unregister_monitor) }, { } }; From patchwork Thu Sep 10 04:35:40 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: 11766547 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 193B7618 for ; Thu, 10 Sep 2020 04:38:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F0AB82078B for ; Thu, 10 Sep 2020 04:38:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="a3AM/fAE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726231AbgIJEiG (ORCPT ); Thu, 10 Sep 2020 00:38:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726324AbgIJEhf (ORCPT ); Thu, 10 Sep 2020 00:37:35 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4733DC061573 for ; Wed, 9 Sep 2020 21:37:32 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id a8so297953plm.2 for ; Wed, 09 Sep 2020 21:37:32 -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=DTPWYPs/pjfsOoexcMwgn/tJlgN2sDx7AxjUE535+Hc=; b=a3AM/fAEvDT9fjJrsUlYOmHaBfNbDK68CJ0TIj6TX3aEOxmcT4w5ABZ12U9Tv1WC0A HxgOZNMjwZIwZvRVBGtEILVSsygcU+p1QeMiAZvNMABrH/l6rmdxUJzadp76WRdkN5bo gTKon61Vv6G0jVa+/vN3OArrZLaEEenU6F1f4= 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=DTPWYPs/pjfsOoexcMwgn/tJlgN2sDx7AxjUE535+Hc=; b=XZ5N3Jd1sCMWLOdQHoKC+GpNNY7UQdH1Uqe/NARuUyEsJpMJiYiBexnPQGvs7lBfSI AR9QH3a34CGvqI6IjEASRq8xUXNlJBXv+qEmFeF2p8/srQtpOU6dMy4w8NN7p6zilJgm JM9BgTYwafjDDDITBivZmxpPhchj6taaX73lLB1YhvDc+7hX+iGUntOB1IhOpakOPh0D xQ+ETqzh/uAtdq16/1LAIBJhZ59mi+d4CKVC/gzWtPbq78z0uI5dvKwmTRrxtN9J5LDh LomyCgUsKI7UOiaaC86l8FD0NxjAj2C/01COF/CyIDR+ncPm6kK2cJHsN6RRUMrBzKxe abdQ== X-Gm-Message-State: AOAM5306CBrJD1vBP7BD2dSuMM5FT5pazBIQGk9gCghNzrQXH9jx8tOz fCNb3Qt1keNwUtX7PotcKN411jtccVoVfA== X-Google-Smtp-Source: ABdhPJybrvAeQhhlWBWpKUugjFJ87Etrb9+dC25d/Tj0QTZSg5hFXimg+6YjY7n1AVPXLMQmOeAXEA== X-Received: by 2002:a17:902:bf4c:: with SMTP id u12mr3686542pls.97.1599712649397; Wed, 09 Sep 2020 21:37:29 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id y4sm4149820pfq.215.2020.09.09.21.37.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:37:28 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou Subject: [BlueZ PATCH v2 5/7] PRE-UPSTREAM: adv_monitor: Handle D-Bus client ready events Date: Wed, 9 Sep 2020 21:35:40 -0700 Message-Id: <20200909213423.BlueZ.v2.5.Id5b1ced1530cb21559bc1dcf29d8764b0c7df825@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- (no changes since v1) src/adv_monitor.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 1a38e6994..23fdc9b14 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -124,9 +124,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; @@ -151,7 +164,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; } @@ -196,7 +211,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", @@ -207,10 +222,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 */ From patchwork Thu Sep 10 04:35:42 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: 11766549 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 D22A8618 for ; Thu, 10 Sep 2020 04:38:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A14C32078B for ; Thu, 10 Sep 2020 04:38:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="I2k7MW2e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725913AbgIJEif (ORCPT ); Thu, 10 Sep 2020 00:38:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726433AbgIJEhs (ORCPT ); Thu, 10 Sep 2020 00:37:48 -0400 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 443DEC061756 for ; Wed, 9 Sep 2020 21:37:48 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id d16so284549pll.13 for ; Wed, 09 Sep 2020 21:37:48 -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=/vY0+mEyZ/SlMy9WNLgOv0mu+n8ZfetJOqGExXjY+jc=; b=I2k7MW2e0ZthTWZ0ksFCmgVUA06Vmtjeb1nc7ryaQ3nUUyz7dxF7NEIF0BXnzVIc7y BC01ThxjMSmuHz/jtCwPipw1yQ6qh/8xMrFtoLNOefwm/HWbpSJgS5w5w7r6vj8ZfJUp NZulEc/YjNR5bpxrETNMgZ6GNpWrwvbEd9QvA= 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=/vY0+mEyZ/SlMy9WNLgOv0mu+n8ZfetJOqGExXjY+jc=; b=sYCZMAsL7aOWCWBA7339GrZgCQX8UGj90x/KoJBeC83BJoNj14Kx2kcdt/cviWZCo+ i305w7nIfQtQFrQBjgeHb7kYvcCezNrs4W0lHfyGniDiOpQCkqD2IcvUzrgys5J17yAv HetqkMDRyG7JBqctyHUrvDT3nGlP/q2SjG9jDbGRUGV3uR3uAEmXKxCBXYuajIGuNCGm mkDSb5u17NMOv7fPg6tS7u3+uRROeb6PNgHNGMDJG6L92oQdJN6EdYaDO+M5DHOKhXqw aawxyQ0KpqjwV9cLcuNC5pLHx/vLIonIWOpH65eAlBbvCVEodN99hTrDYEwMpAzd5faN oYKQ== X-Gm-Message-State: AOAM533a4sWIW4NktA4kFDtYmP06HeSMBpec8ntA5/V5nEQCj7WCHxzk 1/iWeKbhWWJ1GadAXzG51yke8xKvr80dwg== X-Google-Smtp-Source: ABdhPJzkUnWv4hM3eyChlWmfJpLVvx8fjDxozxZNGcFr26e7ZL8sOU83rnQ9WKwc3SILNjtpm8iDHQ== X-Received: by 2002:a17:90a:9412:: with SMTP id r18mr3535253pjo.177.1599712667122; Wed, 09 Sep 2020 21:37: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 y4sm4149820pfq.215.2020.09.09.21.37.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:37:46 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou Subject: [BlueZ PATCH v2 6/7] PRE-UPSTREAM: adv_monitor: Handle D-Bus proxy event of an ADV monitor Date: Wed, 9 Sep 2020 21:35:42 -0700 Message-Id: <20200909213423.BlueZ.v2.6.I47744c7eef31f44cf393dea2b3e437d7b41cef79@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- Changes in v2: - Use new0() instead of g_new0() - Remove the reset of monitor members - Use memcpy() instead of g_memmove() src/adv_monitor.c | 488 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 475 insertions(+), 13 deletions(-) diff --git a/src/adv_monitor.c b/src/adv_monitor.c index 23fdc9b14..b07d886bf 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,48 @@ 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; + + free(pattern); +} + +/* Frees a monitor object */ +static void monitor_free(void *data) +{ + struct adv_monitor *monitor = data; + + if (!monitor) + return; + + g_dbus_proxy_unref(monitor->proxy); + g_free(monitor->path); + + queue_destroy(monitor->patterns, pattern_free); + + 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 +190,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")); @@ -136,6 +235,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 = 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 = new0(struct pattern, 1); + if (!pattern) + goto failed; + + pattern->ad_type = ad_type; + pattern->offset = offset; + pattern->length = value_len; + memcpy(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, @@ -162,8 +627,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); @@ -270,18 +744,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 Thu Sep 10 04:35:44 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: 11766551 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 BBAAB59D for ; Thu, 10 Sep 2020 04:38:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9E1012076D for ; Thu, 10 Sep 2020 04:38:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="R7NQ3PQE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726345AbgIJEik (ORCPT ); Thu, 10 Sep 2020 00:38:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726612AbgIJEig (ORCPT ); Thu, 10 Sep 2020 00:38:36 -0400 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5EC7C061573 for ; Wed, 9 Sep 2020 21:38:35 -0700 (PDT) Received: by mail-pg1-x529.google.com with SMTP id g29so3584296pgl.2 for ; Wed, 09 Sep 2020 21:38:35 -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=OwcQPbWK9wBBKShQmm51i7xxWQDNt4zUBesrzpNnDCQ=; b=R7NQ3PQE0aZ0JhPX44PwcsKwYpCKaHUHx2NVfARomjcVco8wG6Taa7jOOfWD8ujXFl 7XeldgTgFjT6ZjvtQwRWd/fQvmoJYi32w5CSXeeBf6DA3x7MuKanhKvFOQKabVwp7wCF wt5He55q490tuVtxPgEj+gC1iXJiw7iWEw5Sg= 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=OwcQPbWK9wBBKShQmm51i7xxWQDNt4zUBesrzpNnDCQ=; b=EhL9o9kuIvTc1EYv8wy5H9QTb5VcBP5Af3PnwHS3AWuUV559PSMKb44NQRSHhPYkCY bU3uF8F6p4+BMwHTmXCDupjUNCVIT2rNV9TvXlyGRUU3EmCA76kqAMj+cawZZate6RBK qxtiWrq2R81Jr8CQ65dWCnBgxEGCknE3mbmSJAD839ldnattQpVz2aFHsp4d0TC0Y4gc i5opBgnvK6mNObFWBdcPsW5B/ZDHnL8kswnBNWmH2q1ybn2F/ojZYBAJdKMKAs9MUviK Wc9wE1W6DZyqcCcQ+BNBEPebqHPog4mwDLCIWRRbx/O35uNSX0FiSkw0Cd6TPqI3ARIH gyIg== X-Gm-Message-State: AOAM532r0mDazDPP29+51wbcWf761lnD9yQ3gCQuhq65LeOuvkwVqw5g GX+282fpWAsywsyATq95TU1h46LuVNUILw== X-Google-Smtp-Source: ABdhPJz+5RaXIqT8f3AdADKzxAUoo15JNBX5cbprejOmiqFlFuA3fi1UOgp1zbKKNEsnx5noZk71jA== X-Received: by 2002:a65:4c0f:: with SMTP id u15mr2871310pgq.296.1599712713533; Wed, 09 Sep 2020 21:38:33 -0700 (PDT) Received: from mcchou0.mtv.corp.google.com ([2620:15c:202:201:de4a:3eff:fe75:1314]) by smtp.gmail.com with ESMTPSA id y4sm4149820pfq.215.2020.09.09.21.38.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Sep 2020 21:38:32 -0700 (PDT) From: Miao-chen Chou To: Bluetooth Kernel Mailing List Cc: Manish Mandlik , Alain Michaud , Howard Chung , Luiz Augusto von Dentz , Miao-chen Chou Subject: [BlueZ PATCH v2 7/7] doc: Update Advertisement Monitor API description Date: Wed, 9 Sep 2020 21:35:44 -0700 Message-Id: <20200909213423.BlueZ.v2.7.Iee7e9d13c78dd02c5b283a203dea11a4a4ffa7cc@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200909213423.BlueZ.v2.1.I205718871f4e636958904f3cfb171cfd381c54b1@changeid> References: <20200909213423.BlueZ.v2.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 --- (no changes since v1) 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