From patchwork Fri Sep 11 12:09:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 11770373 X-Patchwork-Delegate: luiz.dentz@gmail.com 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 9DC7359D for ; Fri, 11 Sep 2020 12:11:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77C2C221F1 for ; Fri, 11 Sep 2020 12:11:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="DMpK6PYn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725875AbgIKMLd (ORCPT ); Fri, 11 Sep 2020 08:11:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725803AbgIKMJn (ORCPT ); Fri, 11 Sep 2020 08:09:43 -0400 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11003C061573 for ; Fri, 11 Sep 2020 05:09:37 -0700 (PDT) Received: by mail-qk1-x749.google.com with SMTP id w64so5775452qkc.14 for ; Fri, 11 Sep 2020 05:09:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:message-id:mime-version:subject:from:to:cc; bh=H97sd2VMcEYlgRPbkz3+uoOUi+oIFZnIzyaV5V/RIzk=; b=DMpK6PYno1QRfWatKPCOosuNcI1vVCb3CZe1zEMOYxuq90swW7ZUcsuJunMWF9lgF1 hgbqV9NSG1iAsaUIc+fnLN2E3tAroHFxKWnn3YWYJYFTet1dmRkeF6aU2JcwPV/+7L1N Q/twRvGtLtRaaaFokFp2wEalxvHaSjWy4QD7EDNjLplD2v/z3/gFkcIIvoiisBfHlst1 TjXb8l8GSLyyADIlEQSUUe1IOe6S8uDKv02Lb0lrK9EQCznGGJ5eJSNxQZf2iTohTyJm f0ch6q2mRgWzMPRPcF67Wb6Au4kDx5op+FmOaEKLGJrs1monvkPBBWux9S52eu6jF4q/ LUKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:message-id:mime-version:subject:from :to:cc; bh=H97sd2VMcEYlgRPbkz3+uoOUi+oIFZnIzyaV5V/RIzk=; b=W3vMilWaJ2TQhhEi1WuBokDT59URJxVXy8n2fVsNaUlhZM/u2TktsoH4GOi8Q2Bc+j Hi8IECFk6S1GAHgvgg0QGsbtI+IGCyNmuqVFxsmy/yK/BVbJFdKI3oRX3wn6phiszznC FgpV2KyaI4BauMsD9gpUY+27vfxsDnn+IVrzAOcrqZlVvnZsX2IZILhArkhLqgt0GLhB a2uq50RAZrFy/i+LM3T1IRypxlIDFJMow1J2EQxpHINRMNo1VXzUg2T7fZDxbQA5dkpO UvMsozccAuQ5c1yThHXXNWjlpGBgG/WUpMeO3HuBiGsRbxlGCQ/Ud/yYuRuxcZ+XBf9q JzSw== X-Gm-Message-State: AOAM533YA4AWBq7v0dLQHydSbDEKSlgW75uLLJrdt1ODDjE6WS31Hn7v dQqzrUt8NtdlgagZBGb7MPuPueuDNkq4JcMuNaI0tBckVCUeQbH265DQFvt1ZhTVJJ6ARWNvAUQ vwctXInA+LU7355p94rpcsJnRWi/14C+YAoDUjN2Q35nWVIlCtRMR/FC77yBUVP9Q1+mQZSgA3H JGWNdklHsQi6o= X-Google-Smtp-Source: ABdhPJyrxulY0ZPJnplwenh/iF1iepceGch7EeU4NlzJOTqTPLCEMj7JFhQSQiiYJOV8v9wFFnmR0Q3nbk0kBQDiEg== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:f693:9fff:fef4:4e45]) (user=howardchung job=sendgmr) by 2002:a0c:f194:: with SMTP id m20mr1626575qvl.9.1599826176016; Fri, 11 Sep 2020 05:09:36 -0700 (PDT) Date: Fri, 11 Sep 2020 20:09:26 +0800 Message-Id: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> Mime-Version: 1.0 X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [BlueZ PATCH v3 1/4] PRE-UPSTREAM: client: Implement basic interface of ADV monitor in bluetoothctl From: Howard Chung To: linux-bluetooth@vger.kernel.org Cc: mmandlik@chromium.org, mcchou@chromium.org, luiz.von.dentz@intel.com, alainm@chromium.org, Howard Chung Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch implements some basic functions for ADV monitor in bluetoothctl [bluetooth]# show ... Advertisement Monitor Features: SupportedMonitorTypes: or_patterns Reviewed-by: Miao-chen Chou Reviewed-by: Manish Mandlik --- Changes in v3: - Rename advertisement_monitor to adv_monitor Changes in v2: - Update the add-pattern usage - Fix styling issue in patch 1 - Fix storage class declaration issue Makefile.tools | 2 + client/adv_monitor.c | 161 +++++++++++++++++++++++++++++++++++++++++++ client/adv_monitor.h | 23 +++++++ client/main.c | 28 ++++++++ 4 files changed, 214 insertions(+) create mode 100644 client/adv_monitor.c create mode 100644 client/adv_monitor.h diff --git a/Makefile.tools b/Makefile.tools index 9b9236609..ed0fbf8a3 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -7,6 +7,8 @@ client_bluetoothctl_SOURCES = client/main.c \ client/agent.h client/agent.c \ client/advertising.h \ client/advertising.c \ + client/adv_monitor.h \ + client/adv_monitor.c \ client/gatt.h client/gatt.c client_bluetoothctl_LDADD = gdbus/libgdbus-internal.la src/libshared-glib.la \ $(GLIB_LIBS) $(DBUS_LIBS) -lreadline diff --git a/client/adv_monitor.c b/client/adv_monitor.c new file mode 100644 index 000000000..2a62389d9 --- /dev/null +++ b/client/adv_monitor.c @@ -0,0 +1,161 @@ +/* + * + * 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include "gdbus/gdbus.h" +#include "src/shared/util.h" +#include "src/shared/shell.h" +#include "adv_monitor.h" + +#define ADV_MONITOR_APP_PATH "/org/bluez/adv_monitor_app" +#define ADV_MONITOR_INTERFACE "org.bluez.AdvertisementMonitor1" + +static struct adv_monitor_manager { + GSList *supported_types; + GSList *supported_features; + GDBusProxy *proxy; + gboolean app_registered; +} manager = { NULL, NULL, NULL, FALSE }; + +static void set_supported_list(GSList **list, DBusMessageIter *iter) +{ + char *str; + DBusMessageIter subiter; + + dbus_message_iter_recurse(iter, &subiter); + while (dbus_message_iter_get_arg_type(&subiter) == + DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&subiter, &str); + *list = g_slist_append(*list, str); + dbus_message_iter_next(&subiter); + } +} + +void adv_monitor_add_manager(DBusConnection *conn, GDBusProxy *proxy) +{ + DBusMessageIter iter; + + if (manager.proxy != NULL || manager.supported_types != NULL || + manager.supported_features != NULL) { + bt_shell_printf("advertisement monitor manager already " + "added\n"); + return; + } + + manager.proxy = proxy; + + if (g_dbus_proxy_get_property(proxy, "SupportedMonitorTypes", &iter)) + set_supported_list(&(manager.supported_types), &iter); + + if (g_dbus_proxy_get_property(proxy, "SupportedFeatures", &iter)) + set_supported_list(&(manager.supported_features), &iter); + +} + +void adv_monitor_remove_manager(DBusConnection *conn) +{ + if (manager.supported_types != NULL) + g_slist_free(g_steal_pointer(&(manager.supported_types))); + if (manager.supported_features != NULL) + g_slist_free(g_steal_pointer(&(manager.supported_features))); + manager.proxy = NULL; + manager.app_registered = FALSE; +} + +static void register_setup(DBusMessageIter *iter, void *user_data) +{ + const char *path = ADV_MONITOR_APP_PATH; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path); +} + +static void register_reply(DBusMessage *message, void *user_data) +{ + DBusConnection *conn = user_data; + DBusError error; + + dbus_error_init(&error); + + if (dbus_set_error_from_message(&error, message) == FALSE) { + bt_shell_printf("AdvertisementMonitor path registered\n"); + } else { + bt_shell_printf("Failed to register path: %s\n", error.name); + dbus_error_free(&error); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } +} + +static void unregister_setup(DBusMessageIter *iter, void *user_data) +{ + const char *path = ADV_MONITOR_APP_PATH; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path); +} + +static void unregister_reply(DBusMessage *message, void *user_data) +{ + DBusConnection *conn = user_data; + DBusError error; + + dbus_error_init(&error); + + if (dbus_set_error_from_message(&error, message) == FALSE) { + bt_shell_printf("AdvertisementMonitor path unregistered\n"); + return bt_shell_noninteractive_quit(EXIT_SUCCESS); + } + + bt_shell_printf("Failed to unregister Advertisement Monitor:" + " %s\n", error.name); + dbus_error_free(&error); + return bt_shell_noninteractive_quit(EXIT_FAILURE); +} + +void adv_monitor_register_app(DBusConnection *conn) +{ + if (manager.supported_types == NULL || manager.app_registered == TRUE || + g_dbus_proxy_method_call(manager.proxy, "RegisterMonitor", + register_setup, register_reply, + NULL, NULL) == FALSE) { + bt_shell_printf("Failed to register Advertisement Monitor\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + manager.app_registered = TRUE; +} + +void adv_monitor_unregister_app(DBusConnection *conn) +{ + if (manager.app_registered == FALSE || + g_dbus_proxy_method_call(manager.proxy, "UnregisterMonitor", + unregister_setup, unregister_reply, + NULL, NULL) == FALSE) { + bt_shell_printf("Failed to unregister Advertisement Monitor\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + manager.app_registered = FALSE; +} diff --git a/client/adv_monitor.h b/client/adv_monitor.h new file mode 100644 index 000000000..77b0b62c6 --- /dev/null +++ b/client/adv_monitor.h @@ -0,0 +1,23 @@ +/* + * + * 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + */ + +void adv_monitor_add_manager(DBusConnection *conn, GDBusProxy *proxy); +void adv_monitor_remove_manager(DBusConnection *conn); +void adv_monitor_register_app(DBusConnection *conn); +void adv_monitor_unregister_app(DBusConnection *conn); diff --git a/client/main.c b/client/main.c index da877b546..75f8bc462 100644 --- a/client/main.c +++ b/client/main.c @@ -41,6 +41,7 @@ #include "agent.h" #include "gatt.h" #include "advertising.h" +#include "adv_monitor.h" /* String display constants */ #define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF @@ -58,6 +59,7 @@ static char *auto_register_agent = NULL; struct adapter { GDBusProxy *proxy; GDBusProxy *ad_proxy; + GDBusProxy *adv_monitor_proxy; GList *devices; }; @@ -528,6 +530,19 @@ static void ad_manager_added(GDBusProxy *proxy) adapter->ad_proxy = proxy; } +static void admon_manager_added(GDBusProxy *proxy) +{ + struct adapter *adapter; + + adapter = find_ctrl(ctrl_list, g_dbus_proxy_get_path(proxy)); + if (!adapter) + adapter = adapter_new(proxy); + + adapter->adv_monitor_proxy = proxy; + adv_monitor_add_manager(dbus_conn, proxy); + adv_monitor_register_app(dbus_conn); +} + static void proxy_added(GDBusProxy *proxy, void *user_data) { const char *interface; @@ -560,6 +575,9 @@ static void proxy_added(GDBusProxy *proxy, void *user_data) ad_manager_added(proxy); } else if (!strcmp(interface, "org.bluez.Battery1")) { battery_added(proxy); + } else if (!strcmp(interface, + "org.bluez.AdvertisementMonitorManager1")) { + admon_manager_added(proxy); } } @@ -653,6 +671,9 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data) ad_unregister(dbus_conn, NULL); } else if (!strcmp(interface, "org.bluez.Battery1")) { battery_removed(proxy); + } else if (!strcmp(interface, + "org.bluez.AdvertisementMonitorManager1")) { + adv_monitor_remove_manager(dbus_conn); } } @@ -935,6 +956,13 @@ static void cmd_show(int argc, char *argv[]) print_property(adapter->ad_proxy, "SupportedSecondaryChannels"); } + if (adapter->adv_monitor_proxy) { + bt_shell_printf("Advertisement Monitor Features:\n"); + print_property(adapter->adv_monitor_proxy, + "SupportedMonitorTypes"); + print_property(adapter->adv_monitor_proxy, "SupportedFeatures"); + } + return bt_shell_noninteractive_quit(EXIT_SUCCESS); } From patchwork Fri Sep 11 12:09:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 11770371 X-Patchwork-Delegate: luiz.dentz@gmail.com 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 819ED746 for ; Fri, 11 Sep 2020 12:11:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5ABC722206 for ; Fri, 11 Sep 2020 12:11:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="ZzriICdJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725852AbgIKMLB (ORCPT ); Fri, 11 Sep 2020 08:11:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725863AbgIKMJs (ORCPT ); Fri, 11 Sep 2020 08:09:48 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B660DC061757 for ; Fri, 11 Sep 2020 05:09:41 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id q2so6837555pfc.17 for ; Fri, 11 Sep 2020 05:09:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=p9sD2Axl5zUzpyNH9eTboePnANbrOFugW8nMQboWduY=; b=ZzriICdJz7t+dbDamYVtO1nX1qnu8DofWF7De5ZT+yV+AMG9iU05oWppiFHOnWhDMY KnNbQ3x/H9Xum0LLysUR5S1x2gdTL0oHyJFmkSauHVtmhIhR0seV1Oz/ANLLkq+bdQLt cyKusH4fxvDrfpWdziFh+7gTMROqIG6pNt50Ad3OsAOVqDBwxXA9T9R6kUP1fNhfvZsP CA5uJ99vp7yy08YXgtIB9300XSDpqHWtBucLadYRl3YyGE1bvsq7mOr4QDkrf9vaXDE1 l8xuzVxT2uIp2lZcCLXnNhBt5wAxwB4k7CXYwKRkwtJr7cOA+p7l+qHSyZif5+1CZFJT rYYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=p9sD2Axl5zUzpyNH9eTboePnANbrOFugW8nMQboWduY=; b=qnz4cuLLP+d290IN1IAhpePN7G+GyfsCbpOrdPWOjlNg4oRzzZ0QGsI/H3FxKxrHKD kXOjZPocrEufmdSKzYjtzmDItn+NXQs46xH4LbVrJI55YirRSw2vr9Dswh44+F8e4Nq2 BKhWtINHiv220d6mppa8qSuQ/c8e5HacrwDpFTtgEPrqHc0AfX6M1MHHh5x2jMalOVQx rMB/lf5SHTBaQ8cZ9Eal5yy347cdNuJvze7w1q2SVDSQT1i6oL0XgQ9wlqiESR0Oflw5 1btK/+xQRtiUVXoKtWFpXNTsDZLhc+3I6kJXlsIYgYwba/E39S2tkv9m5EIlOG6mDc4w 2Lng== X-Gm-Message-State: AOAM530PRxf5WM7s1QuPU6A7h4tTzHk/tJm1FwBRCqWZHwBQiRItY/55 D5pwwCmqM1ECBNzXDTSZey724AYgiV0d3dFyvmQds+svX6gDCl/QqJNuWNR+dAp0nTEQKiPkHKM cpsiWItvc5BYTIZGcRIGtd5Ci1eA/y/e3pLe7Mwqcy9LWPDhgFLs8E8V/wiDX10ZYtdHLPAitzt i9JFd5y9uSJwM= X-Google-Smtp-Source: ABdhPJzyvBWEVkbAvRwLYboy8Lt8B0JHMTBkIvNgJxjZw5e6xNylVEWbLQWnJmvTrIUZbnY3G43Vu6iCOOOVJ5yYpw== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:f693:9fff:fef4:4e45]) (user=howardchung job=sendgmr) by 2002:a17:90b:15c6:: with SMTP id lh6mr24753pjb.0.1599826180765; Fri, 11 Sep 2020 05:09:40 -0700 (PDT) Date: Fri, 11 Sep 2020 20:09:27 +0800 In-Reply-To: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> Message-Id: <20200911200839.BlueZ.v3.2.Iec6b15e23f4228b80f9b364eb76515d146d592d5@changeid> Mime-Version: 1.0 References: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [BlueZ PATCH v3 2/4] PRE-UPSTREAM: client: Implement more interfaces of ADV monitor in bluetoothctl From: Howard Chung To: linux-bluetooth@vger.kernel.org Cc: mmandlik@chromium.org, mcchou@chromium.org, luiz.von.dentz@intel.com, alainm@chromium.org, Howard Chung Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch creates a submenu in bluetoothctl and implements several commands. new commands: [bluetooth]# menu monitor [bluetooth]# add-or-pattern 1 2 ab0011 Advertisement Monitor 0 added [bluetooth]# add-or-pattern-rssi -80, ,5 1 2 aa 3 4 ff Advertisement Monitor 1 added [bluetooth]# get-pattern all Advertisement Monitor 0 path: /org/bluez/adv_monitor_app/0 type: or_patterns pattern 1: start position: 1 AD data type: 2 content: ab0011 Advertisement Monitor 1 path: /org/bluez/adv_monitor_app/1 type: or_patterns rssi: high threshold: -50 high threshold timer: 5 low threshold: -80 low threshold timer: 5 pattern 1: start position: 1 AD data type: 2 content: aa pattern 2: start position: 3 AD data type: 4 content: ff [bluetooth]# get-supported-info Supported Features: Supported Moniter Types: or_patterns [bluetooth]# remove-pattern 0 Monitor 0 deleted Reviewed-by: Miao-chen Chou Reviewed-by: Manish Mandlik --- (no changes since v2) Changes in v2: - Update the add-pattern usage client/adv_monitor.c | 352 ++++++++++++++++++++++++++++++++++++++++++- client/adv_monitor.h | 10 ++ client/main.c | 109 ++++++++++++++ 3 files changed, 468 insertions(+), 3 deletions(-) diff --git a/client/adv_monitor.c b/client/adv_monitor.c index 2a62389d9..49c0dd01d 100644 --- a/client/adv_monitor.c +++ b/client/adv_monitor.c @@ -29,6 +29,7 @@ #include #include "gdbus/gdbus.h" +#include "src/shared/ad.h" #include "src/shared/util.h" #include "src/shared/shell.h" #include "adv_monitor.h" @@ -36,6 +37,27 @@ #define ADV_MONITOR_APP_PATH "/org/bluez/adv_monitor_app" #define ADV_MONITOR_INTERFACE "org.bluez.AdvertisementMonitor1" +struct rssi_setting { + int16_t high_threshold; + uint16_t high_timer; + int16_t low_threshold; + uint16_t low_timer; +}; + +struct pattern { + uint8_t start_pos; + uint8_t ad_data_type; + uint8_t content_len; + uint8_t content[BT_AD_MAX_DATA_LEN]; +}; + +struct adv_monitor { + uint8_t idx; + char *type; + struct rssi_setting *rssi; + GSList *patterns; +}; + static struct adv_monitor_manager { GSList *supported_types; GSList *supported_features; @@ -43,6 +65,9 @@ static struct adv_monitor_manager { gboolean app_registered; } manager = { NULL, NULL, NULL, FALSE }; +static uint8_t adv_mon_idx; +static GSList *adv_mons; + static void set_supported_list(GSList **list, DBusMessageIter *iter) { char *str; @@ -138,7 +163,10 @@ static void unregister_reply(DBusMessage *message, void *user_data) void adv_monitor_register_app(DBusConnection *conn) { - if (manager.supported_types == NULL || manager.app_registered == TRUE || + if (manager.app_registered == TRUE) { + bt_shell_printf("Advertisement Monitor already registered\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } else if (manager.supported_types == NULL || g_dbus_proxy_method_call(manager.proxy, "RegisterMonitor", register_setup, register_reply, NULL, NULL) == FALSE) { @@ -150,8 +178,10 @@ void adv_monitor_register_app(DBusConnection *conn) void adv_monitor_unregister_app(DBusConnection *conn) { - if (manager.app_registered == FALSE || - g_dbus_proxy_method_call(manager.proxy, "UnregisterMonitor", + if (manager.app_registered == FALSE) { + bt_shell_printf("Advertisement Monitor not registered\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } else if (g_dbus_proxy_method_call(manager.proxy, "UnregisterMonitor", unregister_setup, unregister_reply, NULL, NULL) == FALSE) { bt_shell_printf("Failed to unregister Advertisement Monitor\n"); @@ -159,3 +189,319 @@ void adv_monitor_unregister_app(DBusConnection *conn) } manager.app_registered = FALSE; } + +static void free_pattern(void *user_data) +{ + struct pattern *p = user_data; + + g_free(p); +} + +static void free_adv_monitor(void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + + g_free(adv_monitor->type); + g_free(adv_monitor->rssi); + g_slist_free_full(adv_monitor->patterns, free_pattern); + g_free(adv_monitor); +} + +static uint8_t str2bytearray(char *str, uint8_t *arr) +{ + int idx, len = strlen(str), arr_len = 0; + + if (len%2 != 0) + return 0; + + for (idx = 0; idx < len; idx += 2) { + if (sscanf(str+idx, "%2hhx", &arr[arr_len++]) < 1) + return 0; + } + return arr_len; +} + +static void parse_rssi_value_pair(char *value_pair, int *low, int *high) +{ + char *val1, *val2; + bool flag = value_pair[0] == ','; + + val1 = strtok(value_pair, ","); + + if (!val1) + return; + + val2 = strtok(NULL, ","); + + if (!val2) { + if (!flag) + *low = atoi(val1); + else + *high = atoi(val1); + } else { + *low = atoi(val1); + *high = atoi(val2); + } +} + +static struct rssi_setting *parse_rssi(char *range, char *timeout) +{ + struct rssi_setting *rssi; + int high_threshold, low_threshold, high_timer, low_timer; + + high_threshold = RSSI_DEFAULT_HIGH_THRESHOLD; + low_threshold = RSSI_DEFAULT_LOW_THRESHOLD; + high_timer = RSSI_DEFAULT_HIGH_TIMEOUT; + low_timer = RSSI_DEFAULT_LOW_TIMEOUT; + + parse_rssi_value_pair(range, &low_threshold, &high_threshold); + parse_rssi_value_pair(timeout, &low_timer, &high_timer); + + rssi = g_malloc0(sizeof(struct rssi_setting)); + + if (!rssi) { + bt_shell_printf("Failed to allocate rssi_setting"); + bt_shell_noninteractive_quit(EXIT_FAILURE); + return NULL; + } + + rssi->high_threshold = high_threshold; + rssi->high_timer = high_timer; + rssi->low_threshold = low_threshold; + rssi->low_timer = low_timer; + + return rssi; +} + +static struct pattern *parse_pattern(char *parameter_list[]) +{ + struct pattern *pat; + + pat = g_malloc0(sizeof(struct pattern)); + + if (!pat) { + bt_shell_printf("Failed to allocate pattern"); + bt_shell_noninteractive_quit(EXIT_FAILURE); + return NULL; + } + + pat->start_pos = atoi(parameter_list[0]); + pat->ad_data_type = atoi(parameter_list[1]); + pat->content_len = str2bytearray(parameter_list[2], pat->content); + if (pat->content_len == 0) { + free_pattern(pat); + return NULL; + } + + return pat; +} + +static GSList *parse_patterns(char *pattern_list[], int num) +{ + GSList *patterns = NULL; + int cnt; + + if (num == 0) { + bt_shell_printf("No pattern provided\n"); + return NULL; + } + + if (num%3) { + bt_shell_printf("Expected %d more arguments\n", 3 - num%3); + return NULL; + } + + for (cnt = 0; cnt < num; cnt += 3) { + struct pattern *pattern; + + pattern = parse_pattern(pattern_list+cnt); + if (pattern == NULL) { + g_slist_free_full(patterns, free_pattern); + return NULL; + } + patterns = g_slist_append(patterns, pattern); + } + + return patterns; +} + +static gint cmp_adv_monitor_with_idx(gconstpointer a, gconstpointer b) +{ + const struct adv_monitor *adv_monitor = a; + uint8_t idx = *(uint8_t *)b; + + return adv_monitor->idx != idx; +} + +static struct adv_monitor *find_adv_monitor_with_idx(uint8_t monitor_idx) +{ + GSList *list; + + list = g_slist_find_custom(adv_mons, &monitor_idx, + cmp_adv_monitor_with_idx); + + if (list) + return (struct adv_monitor *)list->data; + return NULL; +} + +static void print_bytearray(char *prefix, uint8_t *arr, uint8_t len) +{ + int idx; + + bt_shell_printf("%s", prefix); + for (idx = 0; idx < len; idx++) + bt_shell_printf("%02hhx", arr[idx]); + bt_shell_printf("\n"); +} + +static void print_adv_monitor(struct adv_monitor *adv_monitor) +{ + GSList *l; + + bt_shell_printf("Advertisement Monitor %d\n", adv_monitor->idx); + bt_shell_printf("\ttype: %s\n", adv_monitor->type); + if (adv_monitor->rssi) { + bt_shell_printf("\trssi:\n"); + bt_shell_printf("\t\thigh threshold: %hd\n", + adv_monitor->rssi->high_threshold); + bt_shell_printf("\t\thigh threshold timer: %hu\n", + adv_monitor->rssi->high_timer); + bt_shell_printf("\t\tlow threshold: %hd\n", + adv_monitor->rssi->low_threshold); + bt_shell_printf("\t\tlow threshold timer: %hu\n", + adv_monitor->rssi->low_timer); + } + + if (adv_monitor->patterns) { + int idx = 1; + + for (l = adv_monitor->patterns; l; l = g_slist_next(l), idx++) { + struct pattern *pattern = l->data; + + bt_shell_printf("\tpattern %d:\n", idx); + bt_shell_printf("\t\tstart position: %hhu\n", + pattern->start_pos); + bt_shell_printf("\t\tAD data type: %hhu\n", + pattern->ad_data_type); + print_bytearray("\t\tcontent: ", pattern->content, + pattern->content_len); + } + } +} + +void adv_monitor_add_monitor(DBusConnection *conn, char *type, + gboolean rssi_enabled, int argc, char *argv[]) +{ + struct adv_monitor *adv_monitor; + struct rssi_setting *rssi; + GSList *patterns = NULL; + + if (g_slist_length(adv_mons) >= UINT8_MAX) { + bt_shell_printf("Number of advertisement monitor exceeds " + "the limit"); + return; + } + + while (find_adv_monitor_with_idx(adv_mon_idx)) + adv_mon_idx += 1; + + if (rssi_enabled == FALSE) + rssi = NULL; + else { + rssi = parse_rssi(argv[1], argv[2]); + if (rssi == NULL) + return; + + argv += 2; + argc -= 2; + } + + patterns = parse_patterns(argv+1, argc-1); + if (patterns == NULL) { + bt_shell_printf("pattern-list malformed\n"); + return; + } + + adv_monitor = g_malloc0(sizeof(struct adv_monitor)); + + if (!adv_monitor) { + bt_shell_printf("Failed to allocate adv_monitor"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + + adv_monitor->idx = adv_mon_idx; + adv_monitor->type = g_strdup(type); + adv_monitor->rssi = rssi; + adv_monitor->patterns = patterns; + + adv_mons = g_slist_append(adv_mons, adv_monitor); + bt_shell_printf("Advertisement Monitor %d added\n", adv_monitor->idx); +} + +void adv_monitor_print_monitor(DBusConnection *conn, int monitor_idx) +{ + struct adv_monitor *adv_monitor; + GSList *l; + + if (monitor_idx < 0) { + for (l = adv_mons; l; l = g_slist_next(l)) { + adv_monitor = l->data; + print_adv_monitor(adv_monitor); + } + return; + } + + adv_monitor = find_adv_monitor_with_idx(monitor_idx); + + if (adv_monitor == NULL) { + bt_shell_printf("Can't find monitor with index %d\n", + monitor_idx); + return; + } + + print_adv_monitor(adv_monitor); +} + +void adv_monitor_remove_monitor(DBusConnection *conn, int monitor_idx) +{ + struct adv_monitor *adv_monitor; + + if (monitor_idx < 0) { + g_slist_free_full(g_steal_pointer(&adv_mons), free_adv_monitor); + return; + } + + adv_monitor = find_adv_monitor_with_idx(monitor_idx); + if (adv_monitor == NULL) { + bt_shell_printf("Can't find monitor with index %d\n", + monitor_idx); + return; + } + + adv_mons = g_slist_remove(adv_mons, adv_monitor); + free_adv_monitor(adv_monitor); + bt_shell_printf("Monitor %d deleted\n", monitor_idx); +} + +static void print_supported_list(GSList *list) +{ + GSList *iter; + + for (iter = list; iter; iter = g_slist_next(iter)) { + char *data = iter->data; + + printf(" %s", data); + } +} + +void adv_monitor_get_supported_info(void) +{ + bt_shell_printf("Supported Features:"); + print_supported_list(manager.supported_features); + bt_shell_printf("\n"); + + bt_shell_printf("Supported Moniter Types:"); + print_supported_list(manager.supported_types); + bt_shell_printf("\n"); +} diff --git a/client/adv_monitor.h b/client/adv_monitor.h index 77b0b62c6..12c01bd3f 100644 --- a/client/adv_monitor.h +++ b/client/adv_monitor.h @@ -17,7 +17,17 @@ * */ +#define RSSI_DEFAULT_HIGH_THRESHOLD -50 +#define RSSI_DEFAULT_LOW_THRESHOLD -70 +#define RSSI_DEFAULT_HIGH_TIMEOUT 10 +#define RSSI_DEFAULT_LOW_TIMEOUT 5 + void adv_monitor_add_manager(DBusConnection *conn, GDBusProxy *proxy); void adv_monitor_remove_manager(DBusConnection *conn); void adv_monitor_register_app(DBusConnection *conn); void adv_monitor_unregister_app(DBusConnection *conn); +void adv_monitor_add_monitor(DBusConnection *conn, char *type, + gboolean rssi_enabled, int argc, char *argv[]); +void adv_monitor_print_monitor(DBusConnection *conn, int monitor_idx); +void adv_monitor_remove_monitor(DBusConnection *conn, int monitor_idx); +void adv_monitor_get_supported_info(void); diff --git a/client/main.c b/client/main.c index 75f8bc462..2b0243308 100644 --- a/client/main.c +++ b/client/main.c @@ -2719,6 +2719,85 @@ static void cmd_ad_clear(int argc, char *argv[]) return bt_shell_noninteractive_quit(EXIT_FAILURE); } +static void print_add_or_pattern_with_rssi_usage(void) +{ + bt_shell_printf("rssi-range format:\n" + "\t,\n" + "\tBoth parameters can be skipped, in that case the\n" + "\tparamter will be set to its pre-defined value\n"); + bt_shell_printf("\tPre-defined low-rssi,high-rssi: %d,%d\n", + RSSI_DEFAULT_LOW_THRESHOLD, + RSSI_DEFAULT_HIGH_THRESHOLD); + bt_shell_printf("timeout format:\n" + "\t,\n" + "\tBoth parameters can be skipped, in that case the\n" + "\tparamter will be set to its pre-defined value\n"); + bt_shell_printf("\tPre-defined low-timeout,high-timeout: %d,%d\n", + RSSI_DEFAULT_LOW_TIMEOUT, + RSSI_DEFAULT_HIGH_TIMEOUT); + bt_shell_printf("pattern format:\n" + "\t \n"); + bt_shell_printf("e.g.\n" + "\tadd-or-pattern-rssi -10, ,10 1 2 01ab55\n"); + bt_shell_printf("or\n" + "\tadd-or-pattern-rssi -50,-30 , 1 2 01ab55 3 4 23cd66\n"); +} + +static void print_add_or_pattern_usage(void) +{ + bt_shell_printf("pattern format:\n" + "\t \n"); + bt_shell_printf("e.g.\n" + "\tadd-or-pattern 1 2 01ab55 3 4 23cd66\n"); +} + +static void cmd_adv_monitor_print_usage(int argc, char *argv[]) +{ + if (strcmp(argv[1], "add-or-pattern") == 0) + print_add_or_pattern_usage(); + else if (strcmp(argv[1], "add-or-pattern-rssi") == 0) + print_add_or_pattern_with_rssi_usage(); + else + bt_shell_printf("Invalid argument %s", argv[1]); +} + +static void cmd_adv_monitor_add_or_monitor_with_rssi(int argc, char *argv[]) +{ + adv_monitor_add_monitor(dbus_conn, "or_patterns", TRUE, argc, argv); +} + +static void cmd_adv_monitor_add_or_monitor(int argc, char *argv[]) +{ + adv_monitor_add_monitor(dbus_conn, "or_patterns", FALSE, argc, argv); +} + +static void cmd_adv_monitor_print_monitor(int argc, char *argv[]) +{ + int monitor_idx; + + if (strcmp(argv[1], "all") == 0) + monitor_idx = -1; + else + monitor_idx = atoi(argv[1]); + adv_monitor_print_monitor(dbus_conn, monitor_idx); +} + +static void cmd_adv_monitor_remove_monitor(int argc, char *argv[]) +{ + int monitor_idx; + + if (strcmp(argv[1], "all") == 0) + monitor_idx = -1; + else + monitor_idx = atoi(argv[1]); + adv_monitor_remove_monitor(dbus_conn, monitor_idx); +} + +static void cmd_adv_monitor_get_supported_info(int argc, char *argv[]) +{ + adv_monitor_get_supported_info(); +} + static const struct bt_shell_menu advertise_menu = { .name = "advertise", .desc = "Advertise Options Submenu", @@ -2755,6 +2834,35 @@ static const struct bt_shell_menu advertise_menu = { { } }, }; +static const struct bt_shell_menu advertise_monitor_menu = { + .name = "monitor", + .desc = "Advertisement Monitor Options Submenu", + .entries = { + { "add-or-pattern-rssi", " " + "[patterns=pattern1 pattern2 ...]", + cmd_adv_monitor_add_or_monitor_with_rssi, + "Add 'or pattern' type monitor with RSSI " + "filter" }, + { "add-or-pattern", "[patterns=pattern1 pattern2 ...]", + cmd_adv_monitor_add_or_monitor, + "Add 'or pattern' type monitor without RSSI " + "filter" }, + { "get-pattern", "", + cmd_adv_monitor_print_monitor, + "Get advertisement monitor" }, + { "remove-pattern", "", + cmd_adv_monitor_remove_monitor, + "Remove advertisement monitor" }, + { "get-supported-info", NULL, + cmd_adv_monitor_get_supported_info, + "Get advertisement manager supported " + "features and supported monitor types" }, + { "print-usage", "", + cmd_adv_monitor_print_usage, + "Print the command usage"}, + { } }, +}; + static const struct bt_shell_menu scan_menu = { .name = "scan", .desc = "Scan Options Submenu", @@ -2932,6 +3040,7 @@ int main(int argc, char *argv[]) bt_shell_init(argc, argv, &opt); bt_shell_set_menu(&main_menu); bt_shell_add_submenu(&advertise_menu); + bt_shell_add_submenu(&advertise_monitor_menu); bt_shell_add_submenu(&scan_menu); bt_shell_add_submenu(&gatt_menu); bt_shell_set_prompt(PROMPT_OFF); From patchwork Fri Sep 11 12:09:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 11770369 X-Patchwork-Delegate: luiz.dentz@gmail.com 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 DBE2D746 for ; Fri, 11 Sep 2020 12:11:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AFFE8221F1 for ; Fri, 11 Sep 2020 12:11:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="oIo5XJv8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725790AbgIKMK6 (ORCPT ); Fri, 11 Sep 2020 08:10:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725787AbgIKMKT (ORCPT ); Fri, 11 Sep 2020 08:10:19 -0400 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98610C0613ED for ; Fri, 11 Sep 2020 05:09:46 -0700 (PDT) Received: by mail-qv1-xf4a.google.com with SMTP id o14so3870823qve.7 for ; Fri, 11 Sep 2020 05:09:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=qIId3xI6bPeFIzMnGT1Pmld70e1Pp7+xu29Zf+ONNsE=; b=oIo5XJv8pbo6JEiRClunbNoPo0YnjMnNG207G3Xf0vsX8AABDlxOiRUlewAdmG9zHI Osyq0KnAiyJ4qlD7HEeiz3PcD+VgJych6Ds7us3Or1233nKoBn34AKtJbz1xgYXEiz2d 3CrTT7ELsOX9g/Sus6DcRci1nQ9kRpcFA5hNBCUOGf5P+w4cPzgUOs+8UO6kwyqv7uLN +S26++P8LSwnALBnqL1cbvSMTy3CXCZr22gjFDOXASvC+/Sp1ISt4AK4HkIKVI2lnUkT L8WX3PIlsuyAD6093qM/cBmmDMKVjK1iQPbPymbLVUwmu6EXowvxGFqtBwgimQZsgHpL CJVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qIId3xI6bPeFIzMnGT1Pmld70e1Pp7+xu29Zf+ONNsE=; b=YCWo+iyLp9pKHsE6kz8ltrSKzI8HM4RgZJWhrFVav2Ih7k7jOINuYv2yFYk7A8FkbG 6ttn4NOLOIwJdV45OKXrJHqJKAfyIjCDaZP52AonXsMSc59Dsg0CCiaiC9rNg0eZOVur a6Lo7a0zHIR7cDGss/dn7sNv4ddIsvGitH9U8gFenRGFDZZByvLAlFj+E2K41pamwXfF qfVKXK6EfvlwHujM3p9m1W+qweouCNf5WTBSYbJ0mj5MZzwQgTWx0ZfQzu2hxj9HGhn4 bOM2jVqq4k9UHvAjFwa3gxdLIEAGokv2HeoXc1FQSUTdWrlfrMprEKvRNiM6H7U8BBI2 EFmA== X-Gm-Message-State: AOAM530JjkUbCE1v0/l4RWY52MWsBboHB2iE9qnKfNLki/a52LLkPU42 Y9/tVLr6+jakYMfSaBHTdOprVVxEPC2jSal5yi0SyY36mxhh4kaaEQRt5iG2NsLxa4mklwabV4M T4cmdzqGHbmzCVPd3TJjuv4UHh9kjQit9we5mQQFTp2YsGJj+PXa1SZz9WMumz/tilE0/TsvVZ+ 2VW/6WDbZ6L0M= X-Google-Smtp-Source: ABdhPJzmKUMKxEWNeUHzuwkis0sb+EWR/ibfD/Kd70xVhwuSDYkbElUUGqDiq6ZgMr2Zk3d2aoC97iuTHelPmZfgEA== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:f693:9fff:fef4:4e45]) (user=howardchung job=sendgmr) by 2002:a0c:f44e:: with SMTP id h14mr1587919qvm.4.1599826185384; Fri, 11 Sep 2020 05:09:45 -0700 (PDT) Date: Fri, 11 Sep 2020 20:09:28 +0800 In-Reply-To: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> Message-Id: <20200911200839.BlueZ.v3.3.I680cda25cec9c45ca2b2c5ac3a8e437772ea76d9@changeid> Mime-Version: 1.0 References: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [BlueZ PATCH v3 3/4] PRE-UPSTREAM: client: Expose ADV monitor objects From: Howard Chung To: linux-bluetooth@vger.kernel.org Cc: mmandlik@chromium.org, mcchou@chromium.org, luiz.von.dentz@intel.com, alainm@chromium.org, Howard Chung Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This adds logic to expose user-defined advertisement monitor to dbus and also implements methods for exposed objects. Reviewed-by: Miao-chen Chou Reviewed-by: Manish Mandlik --- (no changes since v1) client/adv_monitor.c | 185 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 182 insertions(+), 3 deletions(-) diff --git a/client/adv_monitor.c b/client/adv_monitor.c index 49c0dd01d..bb833ffea 100644 --- a/client/adv_monitor.c +++ b/client/adv_monitor.c @@ -53,6 +53,7 @@ struct pattern { struct adv_monitor { uint8_t idx; + char *path; char *type; struct rssi_setting *rssi; GSList *patterns; @@ -68,6 +69,163 @@ static struct adv_monitor_manager { static uint8_t adv_mon_idx; static GSList *adv_mons; +static void remove_adv_monitor(void *data, void *user_data); + +static DBusMessage *release_adv_monitor(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + + bt_shell_printf("Advertisement monitor %d released\n", + adv_monitor->idx); + remove_adv_monitor(adv_monitor, conn); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *activate_adv_monitor(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + + bt_shell_printf("Advertisement monitor %d activated\n", + adv_monitor->idx); + return dbus_message_new_method_return(msg); +} + +static DBusMessage *device_found_adv_monitor(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + const char *device; + + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, + DBUS_TYPE_INVALID); + bt_shell_printf("Advertisement monitor %d found device %s\n", + adv_monitor->idx, device); + return dbus_message_new_method_return(msg); +} + +static DBusMessage *device_lost_adv_monitor(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + const char *device; + + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, + DBUS_TYPE_INVALID); + bt_shell_printf("Advertisement monitor %d lost device %s\n", + adv_monitor->idx, device); + return dbus_message_new_method_return(msg); +} + +static const GDBusMethodTable adv_monitor_methods[] = { + { GDBUS_ASYNC_METHOD("Release", NULL, NULL, release_adv_monitor) }, + { GDBUS_ASYNC_METHOD("Activate", NULL, NULL, activate_adv_monitor) }, + { GDBUS_ASYNC_METHOD("DeviceFound", GDBUS_ARGS({ "device", "o" }), + NULL, device_found_adv_monitor) }, + { GDBUS_ASYNC_METHOD("DeviceLost", GDBUS_ARGS({ "device", "o" }), + NULL, device_lost_adv_monitor) }, + { } +}; + + +static gboolean get_type(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + &adv_monitor->type); + return TRUE; +} + +static gboolean get_rssi(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + struct rssi_setting *rssi = adv_monitor->rssi; + DBusMessageIter data_iter; + + dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, + NULL, &data_iter); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_INT16, + &rssi->high_threshold); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_UINT16, + &rssi->high_timer); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_INT16, + &rssi->low_threshold); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_UINT16, + &rssi->low_timer); + dbus_message_iter_close_container(iter, &data_iter); + return TRUE; +} + +static gboolean rssi_exists(const GDBusPropertyTable *property, void *data) +{ + struct adv_monitor *adv_monitor = data; + + return adv_monitor->rssi != NULL; +} + +static void append_pattern_content_to_dbus(DBusMessageIter *iter, + struct pattern *pattern) +{ + DBusMessageIter data_iter; + int idx; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, &data_iter); + for (idx = 0; idx < pattern->content_len; idx++) + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE, + &pattern->content[idx]); + dbus_message_iter_close_container(iter, &data_iter); +} + +static void append_pattern_to_dbus(void *data, void *user_data) +{ + struct pattern *pattern = data; + DBusMessageIter *array_iter = user_data; + DBusMessageIter data_iter; + + dbus_message_iter_open_container(array_iter, DBUS_TYPE_STRUCT, + NULL, &data_iter); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE, + &pattern->start_pos); + dbus_message_iter_append_basic(&data_iter, DBUS_TYPE_BYTE, + &pattern->ad_data_type); + append_pattern_content_to_dbus(&data_iter, pattern); + dbus_message_iter_close_container(array_iter, &data_iter); +} + +static gboolean get_patterns(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct adv_monitor *adv_monitor = user_data; + DBusMessageIter array_iter; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(yyay)", + &array_iter); + g_slist_foreach(adv_monitor->patterns, append_pattern_to_dbus, + &array_iter); + dbus_message_iter_close_container(iter, &array_iter); + return TRUE; +} + +static gboolean pattern_exists(const GDBusPropertyTable *property, void *data) +{ + struct adv_monitor *adv_monitor = data; + + return adv_monitor->patterns != NULL; +} + +static const GDBusPropertyTable adv_monitor_props[] = { + { "Type", "s", get_type }, + { "RSSIThresholdsAndTimers", "(nqnq)", get_rssi, NULL, rssi_exists }, + { "Patterns", "a(yyay)", get_patterns, NULL, pattern_exists }, + { } +}; + static void set_supported_list(GSList **list, DBusMessageIter *iter) { char *str; @@ -201,6 +359,7 @@ static void free_adv_monitor(void *user_data) { struct adv_monitor *adv_monitor = user_data; + g_free(adv_monitor->path); g_free(adv_monitor->type); g_free(adv_monitor->rssi); g_slist_free_full(adv_monitor->patterns, free_pattern); @@ -325,6 +484,16 @@ static GSList *parse_patterns(char *pattern_list[], int num) return patterns; } +static void remove_adv_monitor(void *data, void *user_data) +{ + struct adv_monitor *adv_monitor = data; + DBusConnection *conn = user_data; + + adv_mons = g_slist_remove(adv_mons, adv_monitor); + g_dbus_unregister_interface(conn, adv_monitor->path, + ADV_MONITOR_INTERFACE); +} + static gint cmp_adv_monitor_with_idx(gconstpointer a, gconstpointer b) { const struct adv_monitor *adv_monitor = a; @@ -360,6 +529,7 @@ static void print_adv_monitor(struct adv_monitor *adv_monitor) GSList *l; bt_shell_printf("Advertisement Monitor %d\n", adv_monitor->idx); + bt_shell_printf("\tpath: %s\n", adv_monitor->path); bt_shell_printf("\ttype: %s\n", adv_monitor->type); if (adv_monitor->rssi) { bt_shell_printf("\trssi:\n"); @@ -434,6 +604,16 @@ void adv_monitor_add_monitor(DBusConnection *conn, char *type, adv_monitor->type = g_strdup(type); adv_monitor->rssi = rssi; adv_monitor->patterns = patterns; + adv_monitor->path = g_strdup_printf("%s/%hhu", ADV_MONITOR_APP_PATH, + adv_mon_idx); + if (g_dbus_register_interface(conn, adv_monitor->path, + ADV_MONITOR_INTERFACE, + adv_monitor_methods, NULL, + adv_monitor_props, adv_monitor, + free_adv_monitor) == FALSE) { + bt_shell_printf("Failed to register advertisement monitor\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } adv_mons = g_slist_append(adv_mons, adv_monitor); bt_shell_printf("Advertisement Monitor %d added\n", adv_monitor->idx); @@ -468,7 +648,7 @@ void adv_monitor_remove_monitor(DBusConnection *conn, int monitor_idx) struct adv_monitor *adv_monitor; if (monitor_idx < 0) { - g_slist_free_full(g_steal_pointer(&adv_mons), free_adv_monitor); + g_slist_foreach(adv_mons, remove_adv_monitor, conn); return; } @@ -479,8 +659,7 @@ void adv_monitor_remove_monitor(DBusConnection *conn, int monitor_idx) return; } - adv_mons = g_slist_remove(adv_mons, adv_monitor); - free_adv_monitor(adv_monitor); + remove_adv_monitor(adv_monitor, conn); bt_shell_printf("Monitor %d deleted\n", monitor_idx); } From patchwork Fri Sep 11 12:09:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Howard Chung X-Patchwork-Id: 11770375 X-Patchwork-Delegate: luiz.dentz@gmail.com 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 63C8C59D for ; Fri, 11 Sep 2020 12:13:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4500D221ED for ; Fri, 11 Sep 2020 12:13:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="tQLDZxIy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725818AbgIKMML (ORCPT ); Fri, 11 Sep 2020 08:12:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725813AbgIKMKp (ORCPT ); Fri, 11 Sep 2020 08:10:45 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDC67C061786 for ; Fri, 11 Sep 2020 05:09:50 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id 78so5960289pgf.5 for ; Fri, 11 Sep 2020 05:09:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=Mx6dIe1hDH83C2Uvj8bO8v9+XJULtPHkuvI4kGsXlTU=; b=tQLDZxIy/tzQaswMkrU95LGQMuZ8szJIH57vivJhYO4bEJny3gbd8LssjMK/+pzPS2 7REI1TMPjV/l9RKFISmXEdRwxVAEYiVTwsVVVXStN9bJ/49owkdwCGtRzn6n/av3jWxJ GFU4V9zYqV2QMNFO0XngR8/AqxMMRlrE/biuz9XkXFu+2kjBz3dRWDz5ZdOA5x4EfcJt 2cDdCFbO6gthGCsxkgGhCBRLyGwVAKOFWsdqLhqfe3AMzluzJ/2tctKpmhDWL9W6Xawz +YLBTRqTQAm0O+N5WZNVcngaUjhsoLjaqGZpT7COYU++xnPS8IyjldI4A7BqTedY2zBB wBUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Mx6dIe1hDH83C2Uvj8bO8v9+XJULtPHkuvI4kGsXlTU=; b=TfTBYIP4fMQFLBXrAanpmNh9GEPIq9cErceBOt8K6VYhg2SBz9na51Q1ASDevFhTwq jbYLFNOkbuLmcdHwfYT8CwQlTlw74gW1Dt9r2HXAcj9LD1sEjm+SgQ7P4CO8//mWKFX/ uofCE0ykbbldh3RI46Q6qWaJyQM7oCgfCAjDjBuClCt3yIkxD7xmT9YfeDNda0fMPIdt s3IQ5ZMbdtnoEKSIvtH7xRBuSpIDgC1cEV4gTmEvvfdFSy35/0fxMDYT1s/7P3EOHmu5 +2nosRbniJShjOWNy8vE1auxkncZU++VI5nPzoIxB+bzzNxh/BhkRsGpKf8wDlikyKHt 1LyQ== X-Gm-Message-State: AOAM532U2UfhYmpcNkrBx8+5qDXqYSuPzHrhR0/8C1w5OuXfxaqeBueq 1hdm/YjUqy9zRp+UcqbNBbSR0kWWjv4SCIpIUVdzJ1lPVGS6WB3UFptaMIn1tRqEU91VWUF2YrY b3e4CFXjva4Es2QoLVdczqLqfFfRQdeeaBTixjFdPGUYCsXpKTaJuyB237J7C1FbGdOMOFZSqHy AnrQtKyRYS844= X-Google-Smtp-Source: ABdhPJwsSBErXN5V6v8ghPcAuA7OgBD2dFzYFXgL1KyIUqAr0nAGiIn8UTis2ctbLNZAcEk+J3Hq2Mpa4avT6TqPTg== X-Received: from howardchung-p920.tpe.corp.google.com ([2401:fa00:1:10:f693:9fff:fef4:4e45]) (user=howardchung job=sendgmr) by 2002:a62:7a05:: with SMTP id v5mr1932342pfc.18.1599826190013; Fri, 11 Sep 2020 05:09:50 -0700 (PDT) Date: Fri, 11 Sep 2020 20:09:29 +0800 In-Reply-To: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> Message-Id: <20200911200839.BlueZ.v3.4.Ieffbe3452565ace2af46a63501c767c8798fd88c@changeid> Mime-Version: 1.0 References: <20200911200839.BlueZ.v3.1.I8e067a74d324751fc788f53e0c14f60923683d01@changeid> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [BlueZ PATCH v3 4/4] PRE-UPSTREAM: core: Add AdvertisementMonitor to bluetooth.conf From: Howard Chung To: linux-bluetooth@vger.kernel.org Cc: mmandlik@chromium.org, mcchou@chromium.org, luiz.von.dentz@intel.com, alainm@chromium.org, Howard Chung Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org AdvertisementMonitor must be included in bluetooth.conf in order to be able to call Release Reviewed-by: Miao-chen Chou Reviewed-by: Manish Mandlik --- (no changes since v1) src/bluetooth.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bluetooth.conf b/src/bluetooth.conf index 8a1e25801..b6c614908 100644 --- a/src/bluetooth.conf +++ b/src/bluetooth.conf @@ -10,6 +10,7 @@ +