Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp543102ybt; Wed, 17 Jun 2020 07:43:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy1Z4atoMAPsRrCfRmH8TPA2EfYjVADQ/SL3j5Aok3UNE6bT37z/Z3bswgxHZrwEr5F+Lfz X-Received: by 2002:a17:907:441c:: with SMTP id om20mr7377292ejb.62.1592405025973; Wed, 17 Jun 2020 07:43:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592405025; cv=none; d=google.com; s=arc-20160816; b=gAdFYgIlpWlFWi1a+WBRr/WzpivJAjI0FcGHMylAEqd9tS+mBDJD1e0q9CxzbiT2FT qOZYChx1arHNXAyXpx0bGd55WpqrvqQ4aqHLVXM6IRauvL/b25QUMmJn/whXH42jgN0F SrYSMyEehosXQQ7WLrYxp6bd3x5mf3luT5BLH0dbv6ZBORptJhervZfYTKKgrfQkBbUw jp0FWJC+HCj5CSu++GZ336rc76lieC2f2xH4GTbXrs4I6GjZx4EXE2M21ubtzKySBFuo M22FhDR1/vS8qQfuT81Wm/wiacvxZuqH0YQDoQIPBqMROd5rtC6j8SorJgdJpp61Fd95 Khzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:to:from; bh=z0CiQmlzT2I8C3o8HXoRJQnPDi4q6pL/BBslLd5kODM=; b=V4LaljXlr9zLZ1QICjodeixE8qPLoanK0dFf5dbENwZnWlkFtL8XqU2VIH7854iruK V01ieT4G1TA+ONs6r1cyCGw8Jw+vhecUk0K3yFfggcV7u5Tlj9k6WAUYEd6pFdTpaCSg S39xoGOHGlbXabOHTbjO0tVPSCDzAef1U7PsqzKGwGGbBP8AL1s5StIxUChaPN0FBRPL ChJGdCsjIqzqaJYESQmrSWkwwgFBV1FrOAYhX39S6rLLUg8FNcvxxPDQTFjJVlODuQHJ cGAlZS3FclA0B5poO5bhy2ibqgxFqFkkFV+4Jr/fgbcOW8qQ7B7DIxQklebgDFAhNBx0 9Wew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q8si113287edn.403.2020.06.17.07.43.22; Wed, 17 Jun 2020 07:43:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726997AbgFQOjg (ORCPT + 99 others); Wed, 17 Jun 2020 10:39:36 -0400 Received: from coyote.holtmann.net ([212.227.132.17]:39578 "EHLO mail.holtmann.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726998AbgFQOj2 (ORCPT ); Wed, 17 Jun 2020 10:39:28 -0400 Received: from localhost.localdomain (p5b3d2638.dip0.t-ipconnect.de [91.61.38.56]) by mail.holtmann.org (Postfix) with ESMTPSA id 4DB01CECDE for ; Wed, 17 Jun 2020 16:49:17 +0200 (CEST) From: Marcel Holtmann To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Date: Wed, 17 Jun 2020 16:39:15 +0200 Message-Id: <211ca797e01a6ccab70d6432bf33ff73ab37d994.1592404644.git.marcel@holtmann.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Miao-chen Chou This adds the request handler of MGMT_OP_REMOVE_ADV_MONITOR command. Note that the controller-based monitoring is not yet in place. This removes the internal monitor(s) without sending HCI traffic, so the request returns immediately. The following test was performed. - Issue btmgmt advmon-remove with valid and invalid handles. Signed-off-by: Miao-chen Chou Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_core.c | 31 ++++++++++++++++++++++++++++ net/bluetooth/mgmt.c | 35 ++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 13fad419ae7d..c54f9295892e 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1283,6 +1283,7 @@ void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired); void hci_adv_monitors_clear(struct hci_dev *hdev); void hci_free_adv_monitor(struct adv_monitor *monitor); int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor); +int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ce481fab349d..59132b3e2cde 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3041,6 +3041,37 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) return 0; } +static int free_adv_monitor(int id, void *ptr, void *data) +{ + struct hci_dev *hdev = data; + struct adv_monitor *monitor = ptr; + + idr_remove(&hdev->adv_monitors_idr, monitor->handle); + hci_free_adv_monitor(monitor); + + return 0; +} + +/* This function requires the caller holds hdev->lock */ +int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle) +{ + struct adv_monitor *monitor; + + if (handle) { + monitor = idr_find(&hdev->adv_monitors_idr, handle); + if (!monitor) + return -ENOENT; + + idr_remove(&hdev->adv_monitors_idr, monitor->handle); + hci_free_adv_monitor(monitor); + } else { + /* Remove all monitors if handle is 0. */ + idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev); + } + + return 0; +} + struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list, bdaddr_t *bdaddr, u8 type) { diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 1eca36e51706..cff24fde72d2 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -121,6 +121,7 @@ static const u16 mgmt_commands[] = { MGMT_OP_SET_DEVICE_FLAGS, MGMT_OP_READ_ADV_MONITOR_FEATURES, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + MGMT_OP_REMOVE_ADV_MONITOR, }; static const u16 mgmt_events[] = { @@ -4118,6 +4119,39 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, return err; } +static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + struct mgmt_cp_remove_adv_monitor *cp = data; + struct mgmt_rp_remove_adv_monitor rp; + u16 handle; + int err; + + BT_DBG("request for %s", hdev->name); + + hci_dev_lock(hdev); + + handle = __le16_to_cpu(cp->monitor_handle); + + err = hci_remove_adv_monitor(hdev, handle); + if (err == -ENOENT) { + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR, + MGMT_STATUS_INVALID_INDEX); + goto unlock; + } + + hci_dev_unlock(hdev); + + rp.monitor_handle = cp->monitor_handle; + + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR, + MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); + +unlock: + hci_dev_unlock(hdev); + return err; +} + static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status, u16 opcode, struct sk_buff *skb) { @@ -7589,6 +7623,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = { { read_adv_mon_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE }, { add_adv_patterns_monitor,MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE, HCI_MGMT_VAR_LEN }, + { remove_adv_monitor, MGMT_REMOVE_ADV_MONITOR_SIZE }, }; void mgmt_index_added(struct hci_dev *hdev) -- 2.26.2