2020-06-17 14:42:52

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 00/14] Combination of pending patches

This is the list of pending patches and fixes merged together. Please
review that the set and functionality is correct and working as
expected.

In v2 the Reviewed-by tags have been added.

Abhishek Pandit-Subedi (4):
Bluetooth: Add bdaddr_list_with_flags for classic whitelist
Bluetooth: Replace wakeable list with flag
Bluetooth: Replace wakeable in hci_conn_params
Bluetooth: Add get/set device flags mgmt op

Manish Mandlik (1):
Bluetooth: Terminate the link if pairing is cancelled

Marcel Holtmann (2):
Bluetooth: mgmt: Add commands for runtime configuration
Bluetooth: mgmt: Use command complete on success for set system config

Miao-chen Chou (7):
Bluetooth: Add definitions for advertisement monitor features
Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
Bluetooth: Notify adv monitor added event
Bluetooth: Notify adv monitor removed event
Bluetooth: Update background scan and report device based on
advertisement monitors

include/net/bluetooth/hci_core.h | 73 +++++-
include/net/bluetooth/mgmt.h | 77 +++++++
net/bluetooth/hci_conn.c | 11 +-
net/bluetooth/hci_core.c | 153 ++++++++++++-
net/bluetooth/hci_event.c | 13 +-
net/bluetooth/hci_request.c | 32 ++-
net/bluetooth/l2cap_core.c | 6 +-
net/bluetooth/mgmt.c | 382 ++++++++++++++++++++++++++++++-
net/bluetooth/mgmt_config.c | 23 +-
net/bluetooth/mgmt_config.h | 6 +
net/bluetooth/msft.c | 7 +
net/bluetooth/msft.h | 9 +
12 files changed, 755 insertions(+), 37 deletions(-)

--
2.26.2


2020-06-17 14:43:45

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 14/14] Bluetooth: mgmt: Use command complete on success for set system config

The command status reply is only for failure. When completing set system
config command, the reply has to be command complete.

Signed-off-by: Marcel Holtmann <[email protected]>
Reviewed-by: Alain Michaud <[email protected]>
---
net/bluetooth/mgmt_config.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/mgmt_config.c b/net/bluetooth/mgmt_config.c
index 8e7ad2a51dbb..8d01a8ff85e9 100644
--- a/net/bluetooth/mgmt_config.c
+++ b/net/bluetooth/mgmt_config.c
@@ -247,9 +247,8 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
buffer += exp_len;
}

- return mgmt_cmd_status(sk, hdev->id,
- MGMT_OP_SET_DEF_SYSTEM_CONFIG,
- MGMT_STATUS_SUCCESS);
+ return mgmt_cmd_complete(sk, hdev->id,
+ MGMT_OP_SET_DEF_SYSTEM_CONFIG, 0, NULL, 0);
}

int read_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
--
2.26.2

2020-06-17 14:43:46

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR

From: Miao-chen Chou <[email protected]>

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 <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
---
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

2020-06-17 14:43:46

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 13/14] Bluetooth: Terminate the link if pairing is cancelled

From: Manish Mandlik <[email protected]>

If user decides to cancel the ongoing pairing process (e.g. by clicking
the cancel button on pairing/passkey window), abort any ongoing pairing
and then terminate the link if it was created because of the pair
device action.

Signed-off-by: Manish Mandlik <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
---
include/net/bluetooth/hci_core.h | 14 ++++++++++++--
net/bluetooth/hci_conn.c | 11 ++++++++---
net/bluetooth/l2cap_core.c | 6 ++++--
net/bluetooth/mgmt.c | 22 ++++++++++++++++++----
4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 524057598ffd..77d29341b064 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -564,6 +564,12 @@ struct hci_dev {

#define HCI_PHY_HANDLE(handle) (handle & 0xff)

+enum conn_reasons {
+ CONN_REASON_PAIR_DEVICE,
+ CONN_REASON_L2CAP_CHAN,
+ CONN_REASON_SCO_CONNECT,
+};
+
struct hci_conn {
struct list_head list;

@@ -615,6 +621,8 @@ struct hci_conn {
__s8 max_tx_power;
unsigned long flags;

+ enum conn_reasons conn_reason;
+
__u32 clock;
__u16 clock_accuracy;

@@ -1040,12 +1048,14 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);

struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level,
- u16 conn_timeout);
+ u16 conn_timeout,
+ enum conn_reasons conn_reason);
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level, u16 conn_timeout,
u8 role, bdaddr_t *direct_rpa);
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
- u8 sec_level, u8 auth_type);
+ u8 sec_level, u8 auth_type,
+ enum conn_reasons conn_reason);
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
__u16 setting);
int hci_conn_check_link_mode(struct hci_conn *conn);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 9bdffc4e79b0..47f3a45d7dcb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1174,7 +1174,8 @@ static int hci_explicit_conn_params_set(struct hci_dev *hdev,
/* This function requires the caller holds hdev->lock */
struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level,
- u16 conn_timeout)
+ u16 conn_timeout,
+ enum conn_reasons conn_reason)
{
struct hci_conn *conn;

@@ -1219,6 +1220,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
conn->sec_level = BT_SECURITY_LOW;
conn->pending_sec_level = sec_level;
conn->conn_timeout = conn_timeout;
+ conn->conn_reason = conn_reason;

hci_update_background_scan(hdev);

@@ -1228,7 +1230,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
}

struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
- u8 sec_level, u8 auth_type)
+ u8 sec_level, u8 auth_type,
+ enum conn_reasons conn_reason)
{
struct hci_conn *acl;

@@ -1248,6 +1251,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,

hci_conn_hold(acl);

+ acl->conn_reason = conn_reason;
if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
acl->sec_level = BT_SECURITY_LOW;
acl->pending_sec_level = sec_level;
@@ -1264,7 +1268,8 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
struct hci_conn *acl;
struct hci_conn *sco;

- acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
+ acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING,
+ CONN_REASON_SCO_CONNECT);
if (IS_ERR(acl))
return acl;

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fe913a5c754a..35d2bc569a2d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7893,11 +7893,13 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
else
hcon = hci_connect_le_scan(hdev, dst, dst_type,
chan->sec_level,
- HCI_LE_CONN_TIMEOUT);
+ HCI_LE_CONN_TIMEOUT,
+ CONN_REASON_L2CAP_CHAN);

} else {
u8 auth_type = l2cap_get_auth_type(chan);
- hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
+ hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type,
+ CONN_REASON_L2CAP_CHAN);
}

if (IS_ERR(hcon)) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ec66160a673c..2a732cab1dc9 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2931,7 +2931,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,

if (cp->addr.type == BDADDR_BREDR) {
conn = hci_connect_acl(hdev, &cp->addr.bdaddr, sec_level,
- auth_type);
+ auth_type, CONN_REASON_PAIR_DEVICE);
} else {
u8 addr_type = le_addr_type(cp->addr.type);
struct hci_conn_params *p;
@@ -2950,9 +2950,9 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT)
p->auto_connect = HCI_AUTO_CONN_DISABLED;

- conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
- addr_type, sec_level,
- HCI_LE_CONN_TIMEOUT);
+ conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr, addr_type,
+ sec_level, HCI_LE_CONN_TIMEOUT,
+ CONN_REASON_PAIR_DEVICE);
}

if (IS_ERR(conn)) {
@@ -3053,6 +3053,20 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,

err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0,
addr, sizeof(*addr));
+
+ /* Since user doesn't want to proceed with the connection, abort any
+ * ongoing pairing and then terminate the link if it was created
+ * because of the pair device action.
+ */
+ if (addr->type == BDADDR_BREDR)
+ hci_remove_link_key(hdev, &addr->bdaddr);
+ else
+ smp_cancel_and_remove_pairing(hdev, &addr->bdaddr,
+ le_addr_type(addr->type));
+
+ if (conn->conn_reason == CONN_REASON_PAIR_DEVICE)
+ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+
unlock:
hci_dev_unlock(hdev);
return err;
--
2.26.2

2020-06-17 14:43:46

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 07/14] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES

From: Miao-chen Chou <[email protected]>

This adds the request handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
command. Since the controller-based monitoring is not yet in place, this
report only the supported features but not the enabled features.

The following test was performed.
- Issuing btmgmt advmon-features.

Signed-off-by: Miao-chen Chou <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
---
include/net/bluetooth/hci_core.h | 24 ++++++++++++++++
net/bluetooth/hci_core.c | 10 ++++++-
net/bluetooth/mgmt.c | 48 ++++++++++++++++++++++++++++++++
net/bluetooth/msft.c | 7 +++++
net/bluetooth/msft.h | 9 ++++++
5 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6f88e5d81bd2..4e9d51087674 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -25,6 +25,7 @@
#ifndef __HCI_CORE_H
#define __HCI_CORE_H

+#include <linux/idr.h>
#include <linux/leds.h>
#include <linux/rculist.h>

@@ -237,6 +238,24 @@ struct adv_info {
#define HCI_MAX_ADV_INSTANCES 5
#define HCI_DEFAULT_ADV_DURATION 2

+struct adv_pattern {
+ struct list_head list;
+ __u8 ad_type;
+ __u8 offset;
+ __u8 length;
+ __u8 value[HCI_MAX_AD_LENGTH];
+};
+
+struct adv_monitor {
+ struct list_head patterns;
+ bool active;
+ __u16 handle;
+};
+
+#define HCI_MIN_ADV_MONITOR_HANDLE 1
+#define HCI_MAX_ADV_MONITOR_NUM_HANDLES 32
+#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS 16
+
#define HCI_MAX_SHORT_NAME_LENGTH 10

/* Min encryption key size to match with SMP */
@@ -511,6 +530,9 @@ struct hci_dev {
__u16 adv_instance_timeout;
struct delayed_work adv_instance_expire;

+ struct idr adv_monitors_idr;
+ unsigned int adv_monitors_cnt;
+
__u8 irk[16];
__u32 rpa_timeout;
struct delayed_work rpa_expired;
@@ -1258,6 +1280,8 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
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_event_packet(struct hci_dev *hdev, struct sk_buff *skb);

void hci_init_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8e01afb2ee8c..53aec32a5850 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -26,7 +26,6 @@
/* Bluetooth HCI core. */

#include <linux/export.h>
-#include <linux/idr.h>
#include <linux/rfkill.h>
#include <linux/debugfs.h>
#include <linux/crypto.h>
@@ -2996,6 +2995,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
return 0;
}

+/* This function requires the caller holds hdev->lock */
+void hci_adv_monitors_clear(struct hci_dev *hdev)
+{
+ idr_destroy(&hdev->adv_monitors_idr);
+}
+
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
bdaddr_t *bdaddr, u8 type)
{
@@ -3646,6 +3651,8 @@ int hci_register_dev(struct hci_dev *hdev)

queue_work(hdev->req_workqueue, &hdev->power_on);

+ idr_init(&hdev->adv_monitors_idr);
+
return id;

err_wqueue:
@@ -3716,6 +3723,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_smp_irks_clear(hdev);
hci_remote_oob_data_clear(hdev);
hci_adv_instances_clear(hdev);
+ hci_adv_monitors_clear(hdev);
hci_bdaddr_list_clear(&hdev->le_white_list);
hci_bdaddr_list_clear(&hdev->le_resolv_list);
hci_conn_params_clear_all(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e409ff48e8e6..8aec7fbe9a38 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -37,6 +37,7 @@
#include "smp.h"
#include "mgmt_util.h"
#include "mgmt_config.h"
+#include "msft.h"

#define MGMT_VERSION 1
#define MGMT_REVISION 17
@@ -118,6 +119,7 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_DEF_RUNTIME_CONFIG,
MGMT_OP_GET_DEVICE_FLAGS,
MGMT_OP_SET_DEVICE_FLAGS,
+ MGMT_OP_READ_ADV_MONITOR_FEATURES,
};

static const u16 mgmt_events[] = {
@@ -3973,6 +3975,51 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
&cp->addr, sizeof(cp->addr));
}

+static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
+ void *data, u16 len)
+{
+ struct adv_monitor *monitor = NULL;
+ struct mgmt_rp_read_adv_monitor_features *rp = NULL;
+ int handle;
+ size_t rp_size = 0;
+ __u32 supported = 0;
+ __u16 num_handles = 0;
+ __u16 handles[HCI_MAX_ADV_MONITOR_NUM_HANDLES];
+
+ BT_DBG("request for %s", hdev->name);
+
+ hci_dev_lock(hdev);
+
+ if (msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR)
+ supported |= MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS;
+
+ idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle) {
+ handles[num_handles++] = monitor->handle;
+ }
+
+ hci_dev_unlock(hdev);
+
+ rp_size = sizeof(*rp) + (num_handles * sizeof(u16));
+ rp = kmalloc(rp_size, GFP_KERNEL);
+ if (!rp)
+ return -ENOMEM;
+
+ /* Once controller-based monitoring is in place, the enabled_features
+ * should reflect the use.
+ */
+ rp->supported_features = cpu_to_le32(supported);
+ rp->enabled_features = 0;
+ rp->max_num_handles = cpu_to_le16(HCI_MAX_ADV_MONITOR_NUM_HANDLES);
+ rp->max_num_patterns = HCI_MAX_ADV_MONITOR_NUM_PATTERNS;
+ rp->num_handles = cpu_to_le16(num_handles);
+ if (num_handles)
+ memcpy(&rp->handles, &handles, (num_handles * sizeof(u16)));
+
+ return mgmt_cmd_complete(sk, hdev->id,
+ MGMT_OP_READ_ADV_MONITOR_FEATURES,
+ MGMT_STATUS_SUCCESS, rp, rp_size);
+}
+
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
u16 opcode, struct sk_buff *skb)
{
@@ -7441,6 +7488,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
HCI_MGMT_VAR_LEN },
{ get_device_flags, MGMT_GET_DEVICE_FLAGS_SIZE },
{ set_device_flags, MGMT_SET_DEVICE_FLAGS_SIZE },
+ { read_adv_mon_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
};

void mgmt_index_added(struct hci_dev *hdev)
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index d6c4e6b5ae77..8579bfeb2836 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -139,3 +139,10 @@ void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)

bt_dev_dbg(hdev, "MSFT vendor event %u", event);
}
+
+__u64 msft_get_features(struct hci_dev *hdev)
+{
+ struct msft_data *msft = hdev->msft_data;
+
+ return msft ? msft->features : 0;
+}
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
index 5aa9130e1f8a..e9c478e890b8 100644
--- a/net/bluetooth/msft.h
+++ b/net/bluetooth/msft.h
@@ -3,16 +3,25 @@
* Copyright (C) 2020 Google Corporation
*/

+#define MSFT_FEATURE_MASK_BREDR_RSSI_MONITOR BIT(0)
+#define MSFT_FEATURE_MASK_LE_CONN_RSSI_MONITOR BIT(1)
+#define MSFT_FEATURE_MASK_LE_ADV_RSSI_MONITOR BIT(2)
+#define MSFT_FEATURE_MASK_LE_ADV_MONITOR BIT(3)
+#define MSFT_FEATURE_MASK_CURVE_VALIDITY BIT(4)
+#define MSFT_FEATURE_MASK_CONCURRENT_ADV_MONITOR BIT(5)
+
#if IS_ENABLED(CONFIG_BT_MSFTEXT)

void msft_do_open(struct hci_dev *hdev);
void msft_do_close(struct hci_dev *hdev);
void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
+__u64 msft_get_features(struct hci_dev *hdev);

#else

static inline void msft_do_open(struct hci_dev *hdev) {}
static inline void msft_do_close(struct hci_dev *hdev) {}
static inline void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb) {}
+static inline __u64 msft_get_features(struct hci_dev *hdev) { return 0; }

#endif
--
2.26.2

2020-06-17 14:43:46

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op

From: Abhishek Pandit-Subedi <[email protected]>

Add the get device flags and set device flags mgmt ops and the device
flags changed event. Their behavior is described in detail in
mgmt-api.txt in bluez.

Sample btmon trace when a HID device is added (trimmed to 75 chars):

@ MGMT Command: Unknown (0x0050) plen 11 {0x0001} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 ...........
@ MGMT Event: Unknown (0x002a) plen 15 {0x0004} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Unknown (0x002a) plen 15 {0x0003} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Unknown (0x002a) plen 15 {0x0002} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Command Compl.. (0x0001) plen 10 {0x0001} [hci0] 18:06:14.98
Unknown (0x0050) plen 7
Status: Success (0x00)
90 c5 13 cd f3 cd 02 .......
@ MGMT Command: Add Device (0x0033) plen 8 {0x0001} [hci0] 18:06:14.98
LE Address: CD:F3:CD:13:C5:90 (Static)
Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8 {0x0004} [hci0] 18:06:14.98
LE Address: CD:F3:CD:13:C5:90 (Static)
Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8 {0x0003} [hci0] 18:06:14.98
LE Address: CD:F3:CD:13:C5:90 (Static)
Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8 {0x0002} [hci0] 18:06:14.98
LE Address: CD:F3:CD:13:C5:90 (Static)
Action: Auto-connect remote device (0x02)
@ MGMT Event: Unknown (0x002a) plen 15 {0x0004} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Unknown (0x002a) plen 15 {0x0003} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Unknown (0x002a) plen 15 {0x0002} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
@ MGMT Event: Unknown (0x002a) plen 15 {0x0001} [hci0] 18:06:14.98
90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............

Signed-off-by: Abhishek Pandit-Subedi <[email protected]>
Reviewed-by: Alain Michaud <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
---
include/net/bluetooth/mgmt.h | 28 ++++++++
net/bluetooth/mgmt.c | 128 +++++++++++++++++++++++++++++++++++
2 files changed, 156 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index e515288f328f..8e47b0c5fe52 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -720,6 +720,27 @@ struct mgmt_rp_set_exp_feature {
#define MGMT_OP_SET_DEF_RUNTIME_CONFIG 0x004e
#define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE 0

+#define MGMT_OP_GET_DEVICE_FLAGS 0x004F
+#define MGMT_GET_DEVICE_FLAGS_SIZE 7
+struct mgmt_cp_get_device_flags {
+ struct mgmt_addr_info addr;
+} __packed;
+struct mgmt_rp_get_device_flags {
+ struct mgmt_addr_info addr;
+ __le32 supported_flags;
+ __le32 current_flags;
+} __packed;
+
+#define MGMT_OP_SET_DEVICE_FLAGS 0x0050
+#define MGMT_SET_DEVICE_FLAGS_SIZE 11
+struct mgmt_cp_set_device_flags {
+ struct mgmt_addr_info addr;
+ __le32 current_flags;
+} __packed;
+struct mgmt_rp_set_device_flags {
+ struct mgmt_addr_info addr;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -951,3 +972,10 @@ struct mgmt_ev_exp_feature_changed {
__u8 uuid[16];
__le32 flags;
} __packed;
+
+#define MGMT_EV_DEVICE_FLAGS_CHANGED 0x002a
+struct mgmt_ev_device_flags_changed {
+ struct mgmt_addr_info addr;
+ __le32 supported_flags;
+ __le32 current_flags;
+} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d0d0fa832c8a..e409ff48e8e6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -116,6 +116,8 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_DEF_SYSTEM_CONFIG,
MGMT_OP_READ_DEF_RUNTIME_CONFIG,
MGMT_OP_SET_DEF_RUNTIME_CONFIG,
+ MGMT_OP_GET_DEVICE_FLAGS,
+ MGMT_OP_SET_DEVICE_FLAGS,
};

static const u16 mgmt_events[] = {
@@ -156,6 +158,7 @@ static const u16 mgmt_events[] = {
MGMT_EV_EXT_INFO_CHANGED,
MGMT_EV_PHY_CONFIGURATION_CHANGED,
MGMT_EV_EXP_FEATURE_CHANGED,
+ MGMT_EV_DEVICE_FLAGS_CHANGED,
};

static const u16 mgmt_untrusted_commands[] = {
@@ -3856,6 +3859,120 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
MGMT_STATUS_NOT_SUPPORTED);
}

+#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1)
+
+static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
+ u16 data_len)
+{
+ struct mgmt_cp_get_device_flags *cp = data;
+ struct mgmt_rp_get_device_flags rp;
+ struct bdaddr_list_with_flags *br_params;
+ struct hci_conn_params *params;
+ u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+ u32 current_flags = 0;
+ u8 status = MGMT_STATUS_INVALID_PARAMS;
+
+ bt_dev_dbg(hdev, "Get device flags %pMR (type 0x%x)\n",
+ &cp->addr.bdaddr, cp->addr.type);
+
+ if (cp->addr.type == BDADDR_BREDR) {
+ br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
+ &cp->addr.bdaddr,
+ cp->addr.type);
+ if (!br_params)
+ goto done;
+
+ current_flags = br_params->current_flags;
+ } else {
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+
+ if (!params)
+ goto done;
+
+ current_flags = params->current_flags;
+ }
+
+ bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
+ rp.addr.type = cp->addr.type;
+ rp.supported_flags = cpu_to_le32(supported_flags);
+ rp.current_flags = cpu_to_le32(current_flags);
+
+ status = MGMT_STATUS_SUCCESS;
+
+done:
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_DEVICE_FLAGS, status,
+ &rp, sizeof(rp));
+}
+
+static void device_flags_changed(struct sock *sk, struct hci_dev *hdev,
+ bdaddr_t *bdaddr, u8 bdaddr_type,
+ u32 supported_flags, u32 current_flags)
+{
+ struct mgmt_ev_device_flags_changed ev;
+
+ bacpy(&ev.addr.bdaddr, bdaddr);
+ ev.addr.type = bdaddr_type;
+ ev.supported_flags = cpu_to_le32(supported_flags);
+ ev.current_flags = cpu_to_le32(current_flags);
+
+ mgmt_event(MGMT_EV_DEVICE_FLAGS_CHANGED, hdev, &ev, sizeof(ev), sk);
+}
+
+static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
+ u16 len)
+{
+ struct mgmt_cp_set_device_flags *cp = data;
+ struct bdaddr_list_with_flags *br_params;
+ struct hci_conn_params *params;
+ u8 status = MGMT_STATUS_INVALID_PARAMS;
+ u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+ u32 current_flags = __le32_to_cpu(cp->current_flags);
+
+ bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
+ &cp->addr.bdaddr, cp->addr.type,
+ __le32_to_cpu(current_flags));
+
+ if ((supported_flags | current_flags) != supported_flags) {
+ bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
+ current_flags, supported_flags);
+ goto done;
+ }
+
+ if (cp->addr.type == BDADDR_BREDR) {
+ br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
+ &cp->addr.bdaddr,
+ cp->addr.type);
+
+ if (br_params) {
+ br_params->current_flags = current_flags;
+ status = MGMT_STATUS_SUCCESS;
+ } else {
+ bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
+ &cp->addr.bdaddr, cp->addr.type);
+ }
+ } else {
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+ if (params) {
+ params->current_flags = current_flags;
+ status = MGMT_STATUS_SUCCESS;
+ } else {
+ bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
+ &cp->addr.bdaddr,
+ le_addr_type(cp->addr.type));
+ }
+ }
+
+done:
+ if (status == MGMT_STATUS_SUCCESS)
+ device_flags_changed(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
+ supported_flags, current_flags);
+
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_FLAGS, status,
+ &cp->addr, sizeof(cp->addr));
+}
+
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
u16 opcode, struct sk_buff *skb)
{
@@ -5973,7 +6090,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
{
struct mgmt_cp_add_device *cp = data;
u8 auto_conn, addr_type;
+ struct hci_conn_params *params;
int err;
+ u32 current_flags = 0;

bt_dev_dbg(hdev, "sock %p", sk);

@@ -6041,12 +6160,19 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
MGMT_STATUS_FAILED, &cp->addr,
sizeof(cp->addr));
goto unlock;
+ } else {
+ params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+ addr_type);
+ if (params)
+ current_flags = params->current_flags;
}

hci_update_background_scan(hdev);

added:
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
+ device_flags_changed(NULL, hdev, &cp->addr.bdaddr, cp->addr.type,
+ SUPPORTED_DEVICE_FLAGS(), current_flags);

err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_SUCCESS, &cp->addr,
@@ -7313,6 +7439,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
HCI_MGMT_UNTRUSTED },
{ set_def_runtime_config, MGMT_SET_DEF_RUNTIME_CONFIG_SIZE,
HCI_MGMT_VAR_LEN },
+ { get_device_flags, MGMT_GET_DEVICE_FLAGS_SIZE },
+ { set_device_flags, MGMT_SET_DEVICE_FLAGS_SIZE },
};

void mgmt_index_added(struct hci_dev *hdev)
--
2.26.2

2020-06-17 18:04:57

by Abhishek Pandit-Subedi

[permalink] [raw]
Subject: Re: [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op

Hi Marcel,

This looks good to me. Thanks for removing
HCI_MGMT_DEVICE_FLAGS_EVENTS -- I misunderstood what it was for.

Abhishek

On Wed, Jun 17, 2020 at 7:39 AM Marcel Holtmann <[email protected]> wrote:
>
> From: Abhishek Pandit-Subedi <[email protected]>
>
> Add the get device flags and set device flags mgmt ops and the device
> flags changed event. Their behavior is described in detail in
> mgmt-api.txt in bluez.
>
> Sample btmon trace when a HID device is added (trimmed to 75 chars):
>
> @ MGMT Command: Unknown (0x0050) plen 11 {0x0001} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 ...........
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0004} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0003} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0002} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Command Compl.. (0x0001) plen 10 {0x0001} [hci0] 18:06:14.98
> Unknown (0x0050) plen 7
> Status: Success (0x00)
> 90 c5 13 cd f3 cd 02 .......
> @ MGMT Command: Add Device (0x0033) plen 8 {0x0001} [hci0] 18:06:14.98
> LE Address: CD:F3:CD:13:C5:90 (Static)
> Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8 {0x0004} [hci0] 18:06:14.98
> LE Address: CD:F3:CD:13:C5:90 (Static)
> Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8 {0x0003} [hci0] 18:06:14.98
> LE Address: CD:F3:CD:13:C5:90 (Static)
> Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8 {0x0002} [hci0] 18:06:14.98
> LE Address: CD:F3:CD:13:C5:90 (Static)
> Action: Auto-connect remote device (0x02)
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0004} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0003} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0002} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
> @ MGMT Event: Unknown (0x002a) plen 15 {0x0001} [hci0] 18:06:14.98
> 90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00 ...............
>
> Signed-off-by: Abhishek Pandit-Subedi <[email protected]>
> Reviewed-by: Alain Michaud <[email protected]>
> Signed-off-by: Marcel Holtmann <[email protected]>
> ---
> include/net/bluetooth/mgmt.h | 28 ++++++++
> net/bluetooth/mgmt.c | 128 +++++++++++++++++++++++++++++++++++
> 2 files changed, 156 insertions(+)
>
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index e515288f328f..8e47b0c5fe52 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -720,6 +720,27 @@ struct mgmt_rp_set_exp_feature {
> #define MGMT_OP_SET_DEF_RUNTIME_CONFIG 0x004e
> #define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE 0
>
> +#define MGMT_OP_GET_DEVICE_FLAGS 0x004F
> +#define MGMT_GET_DEVICE_FLAGS_SIZE 7
> +struct mgmt_cp_get_device_flags {
> + struct mgmt_addr_info addr;
> +} __packed;
> +struct mgmt_rp_get_device_flags {
> + struct mgmt_addr_info addr;
> + __le32 supported_flags;
> + __le32 current_flags;
> +} __packed;
> +
> +#define MGMT_OP_SET_DEVICE_FLAGS 0x0050
> +#define MGMT_SET_DEVICE_FLAGS_SIZE 11
> +struct mgmt_cp_set_device_flags {
> + struct mgmt_addr_info addr;
> + __le32 current_flags;
> +} __packed;
> +struct mgmt_rp_set_device_flags {
> + struct mgmt_addr_info addr;
> +} __packed;
> +
> #define MGMT_EV_CMD_COMPLETE 0x0001
> struct mgmt_ev_cmd_complete {
> __le16 opcode;
> @@ -951,3 +972,10 @@ struct mgmt_ev_exp_feature_changed {
> __u8 uuid[16];
> __le32 flags;
> } __packed;
> +
> +#define MGMT_EV_DEVICE_FLAGS_CHANGED 0x002a
> +struct mgmt_ev_device_flags_changed {
> + struct mgmt_addr_info addr;
> + __le32 supported_flags;
> + __le32 current_flags;
> +} __packed;
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index d0d0fa832c8a..e409ff48e8e6 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -116,6 +116,8 @@ static const u16 mgmt_commands[] = {
> MGMT_OP_SET_DEF_SYSTEM_CONFIG,
> MGMT_OP_READ_DEF_RUNTIME_CONFIG,
> MGMT_OP_SET_DEF_RUNTIME_CONFIG,
> + MGMT_OP_GET_DEVICE_FLAGS,
> + MGMT_OP_SET_DEVICE_FLAGS,
> };
>
> static const u16 mgmt_events[] = {
> @@ -156,6 +158,7 @@ static const u16 mgmt_events[] = {
> MGMT_EV_EXT_INFO_CHANGED,
> MGMT_EV_PHY_CONFIGURATION_CHANGED,
> MGMT_EV_EXP_FEATURE_CHANGED,
> + MGMT_EV_DEVICE_FLAGS_CHANGED,
> };
>
> static const u16 mgmt_untrusted_commands[] = {
> @@ -3856,6 +3859,120 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
> MGMT_STATUS_NOT_SUPPORTED);
> }
>
> +#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1)
> +
> +static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
> + u16 data_len)
> +{
> + struct mgmt_cp_get_device_flags *cp = data;
> + struct mgmt_rp_get_device_flags rp;
> + struct bdaddr_list_with_flags *br_params;
> + struct hci_conn_params *params;
> + u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
> + u32 current_flags = 0;
> + u8 status = MGMT_STATUS_INVALID_PARAMS;
> +
> + bt_dev_dbg(hdev, "Get device flags %pMR (type 0x%x)\n",
> + &cp->addr.bdaddr, cp->addr.type);
> +
> + if (cp->addr.type == BDADDR_BREDR) {
> + br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
> + &cp->addr.bdaddr,
> + cp->addr.type);
> + if (!br_params)
> + goto done;
> +
> + current_flags = br_params->current_flags;
> + } else {
> + params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> + le_addr_type(cp->addr.type));
> +
> + if (!params)
> + goto done;
> +
> + current_flags = params->current_flags;
> + }
> +
> + bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
> + rp.addr.type = cp->addr.type;
> + rp.supported_flags = cpu_to_le32(supported_flags);
> + rp.current_flags = cpu_to_le32(current_flags);
> +
> + status = MGMT_STATUS_SUCCESS;
> +
> +done:
> + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_DEVICE_FLAGS, status,
> + &rp, sizeof(rp));
> +}
> +
> +static void device_flags_changed(struct sock *sk, struct hci_dev *hdev,
> + bdaddr_t *bdaddr, u8 bdaddr_type,
> + u32 supported_flags, u32 current_flags)
> +{
> + struct mgmt_ev_device_flags_changed ev;
> +
> + bacpy(&ev.addr.bdaddr, bdaddr);
> + ev.addr.type = bdaddr_type;
> + ev.supported_flags = cpu_to_le32(supported_flags);
> + ev.current_flags = cpu_to_le32(current_flags);
> +
> + mgmt_event(MGMT_EV_DEVICE_FLAGS_CHANGED, hdev, &ev, sizeof(ev), sk);
> +}
> +
> +static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
> + u16 len)
> +{
> + struct mgmt_cp_set_device_flags *cp = data;
> + struct bdaddr_list_with_flags *br_params;
> + struct hci_conn_params *params;
> + u8 status = MGMT_STATUS_INVALID_PARAMS;
> + u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
> + u32 current_flags = __le32_to_cpu(cp->current_flags);
> +
> + bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
> + &cp->addr.bdaddr, cp->addr.type,
> + __le32_to_cpu(current_flags));
> +
> + if ((supported_flags | current_flags) != supported_flags) {
> + bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
> + current_flags, supported_flags);
> + goto done;
> + }
> +
> + if (cp->addr.type == BDADDR_BREDR) {
> + br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
> + &cp->addr.bdaddr,
> + cp->addr.type);
> +
> + if (br_params) {
> + br_params->current_flags = current_flags;
> + status = MGMT_STATUS_SUCCESS;
> + } else {
> + bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
> + &cp->addr.bdaddr, cp->addr.type);
> + }
> + } else {
> + params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> + le_addr_type(cp->addr.type));
> + if (params) {
> + params->current_flags = current_flags;
> + status = MGMT_STATUS_SUCCESS;
> + } else {
> + bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
> + &cp->addr.bdaddr,
> + le_addr_type(cp->addr.type));
> + }
> + }
> +
> +done:
> + if (status == MGMT_STATUS_SUCCESS)
> + device_flags_changed(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
> + supported_flags, current_flags);
> +
> + return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_FLAGS, status,
> + &cp->addr, sizeof(cp->addr));
> +}
> +
> static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
> u16 opcode, struct sk_buff *skb)
> {
> @@ -5973,7 +6090,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
> {
> struct mgmt_cp_add_device *cp = data;
> u8 auto_conn, addr_type;
> + struct hci_conn_params *params;
> int err;
> + u32 current_flags = 0;
>
> bt_dev_dbg(hdev, "sock %p", sk);
>
> @@ -6041,12 +6160,19 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
> MGMT_STATUS_FAILED, &cp->addr,
> sizeof(cp->addr));
> goto unlock;
> + } else {
> + params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> + addr_type);
> + if (params)
> + current_flags = params->current_flags;
> }
>
> hci_update_background_scan(hdev);
>
> added:
> device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
> + device_flags_changed(NULL, hdev, &cp->addr.bdaddr, cp->addr.type,
> + SUPPORTED_DEVICE_FLAGS(), current_flags);
>
> err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
> MGMT_STATUS_SUCCESS, &cp->addr,
> @@ -7313,6 +7439,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
> HCI_MGMT_UNTRUSTED },
> { set_def_runtime_config, MGMT_SET_DEF_RUNTIME_CONFIG_SIZE,
> HCI_MGMT_VAR_LEN },
> + { get_device_flags, MGMT_GET_DEVICE_FLAGS_SIZE },
> + { set_device_flags, MGMT_SET_DEVICE_FLAGS_SIZE },
> };
>
> void mgmt_index_added(struct hci_dev *hdev)
> --
> 2.26.2
>

2020-06-18 10:20:59

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v2 00/14] Combination of pending patches

Hi Marcel,

On Wed, Jun 17, 2020, Marcel Holtmann wrote:
> This is the list of pending patches and fixes merged together. Please
> review that the set and functionality is correct and working as
> expected.
>
> In v2 the Reviewed-by tags have been added.
>
> Abhishek Pandit-Subedi (4):
> Bluetooth: Add bdaddr_list_with_flags for classic whitelist
> Bluetooth: Replace wakeable list with flag
> Bluetooth: Replace wakeable in hci_conn_params
> Bluetooth: Add get/set device flags mgmt op
>
> Manish Mandlik (1):
> Bluetooth: Terminate the link if pairing is cancelled
>
> Marcel Holtmann (2):
> Bluetooth: mgmt: Add commands for runtime configuration
> Bluetooth: mgmt: Use command complete on success for set system config
>
> Miao-chen Chou (7):
> Bluetooth: Add definitions for advertisement monitor features
> Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
> Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
> Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
> Bluetooth: Notify adv monitor added event
> Bluetooth: Notify adv monitor removed event
> Bluetooth: Update background scan and report device based on
> advertisement monitors
>
> include/net/bluetooth/hci_core.h | 73 +++++-
> include/net/bluetooth/mgmt.h | 77 +++++++
> net/bluetooth/hci_conn.c | 11 +-
> net/bluetooth/hci_core.c | 153 ++++++++++++-
> net/bluetooth/hci_event.c | 13 +-
> net/bluetooth/hci_request.c | 32 ++-
> net/bluetooth/l2cap_core.c | 6 +-
> net/bluetooth/mgmt.c | 382 ++++++++++++++++++++++++++++++-
> net/bluetooth/mgmt_config.c | 23 +-
> net/bluetooth/mgmt_config.h | 6 +
> net/bluetooth/msft.c | 7 +
> net/bluetooth/msft.h | 9 +
> 12 files changed, 755 insertions(+), 37 deletions(-)

All patches in this set have been applied to bluetooth-next. Thanks.

Johan