|
@@ -37,7 +37,7 @@
|
|
|
#include "smp.h"
|
|
|
|
|
|
#define MGMT_VERSION 1
|
|
|
-#define MGMT_REVISION 8
|
|
|
+#define MGMT_REVISION 9
|
|
|
|
|
|
static const u16 mgmt_commands[] = {
|
|
|
MGMT_OP_READ_INDEX_LIST,
|
|
@@ -135,7 +135,7 @@ static const u16 mgmt_events[] = {
|
|
|
#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
|
|
|
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
|
|
|
|
-struct pending_cmd {
|
|
|
+struct mgmt_pending_cmd {
|
|
|
struct list_head list;
|
|
|
u16 opcode;
|
|
|
int index;
|
|
@@ -143,7 +143,7 @@ struct pending_cmd {
|
|
|
size_t param_len;
|
|
|
struct sock *sk;
|
|
|
void *user_data;
|
|
|
- int (*cmd_complete)(struct pending_cmd *cmd, u8 status);
|
|
|
+ int (*cmd_complete)(struct mgmt_pending_cmd *cmd, u8 status);
|
|
|
};
|
|
|
|
|
|
/* HCI to MGMT error code conversion table */
|
|
@@ -219,8 +219,9 @@ static u8 mgmt_status(u8 hci_status)
|
|
|
return MGMT_STATUS_FAILED;
|
|
|
}
|
|
|
|
|
|
-static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
|
|
|
- struct sock *skip_sk)
|
|
|
+static int mgmt_send_event(u16 event, struct hci_dev *hdev,
|
|
|
+ unsigned short channel, void *data, u16 data_len,
|
|
|
+ struct sock *skip_sk)
|
|
|
{
|
|
|
struct sk_buff *skb;
|
|
|
struct mgmt_hdr *hdr;
|
|
@@ -243,13 +244,20 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
|
|
|
/* Time stamp */
|
|
|
__net_timestamp(skb);
|
|
|
|
|
|
- hci_send_to_channel(HCI_CHANNEL_CONTROL, skb, skip_sk);
|
|
|
+ hci_send_to_channel(channel, skb, skip_sk);
|
|
|
kfree_skb(skb);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
|
|
|
+static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 len,
|
|
|
+ struct sock *skip_sk)
|
|
|
+{
|
|
|
+ return mgmt_send_event(event, hdev, HCI_CHANNEL_CONTROL, data, len,
|
|
|
+ skip_sk);
|
|
|
+}
|
|
|
+
|
|
|
+static int mgmt_cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
|
|
|
{
|
|
|
struct sk_buff *skb;
|
|
|
struct mgmt_hdr *hdr;
|
|
@@ -279,8 +287,8 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
|
|
- void *rp, size_t rp_len)
|
|
|
+static int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
|
|
|
+ void *rp, size_t rp_len)
|
|
|
{
|
|
|
struct sk_buff *skb;
|
|
|
struct mgmt_hdr *hdr;
|
|
@@ -323,8 +331,8 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.version = MGMT_VERSION;
|
|
|
rp.revision = cpu_to_le16(MGMT_REVISION);
|
|
|
|
|
|
- return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp,
|
|
|
- sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0,
|
|
|
+ &rp, sizeof(rp));
|
|
|
}
|
|
|
|
|
|
static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
@@ -354,8 +362,8 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
for (i = 0; i < num_events; i++, opcode++)
|
|
|
put_unaligned_le16(mgmt_events[i], opcode);
|
|
|
|
|
|
- err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, rp,
|
|
|
- rp_size);
|
|
|
+ err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0,
|
|
|
+ rp, rp_size);
|
|
|
kfree(rp);
|
|
|
|
|
|
return err;
|
|
@@ -377,7 +385,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
count = 0;
|
|
|
list_for_each_entry(d, &hci_dev_list, list) {
|
|
|
if (d->dev_type == HCI_BREDR &&
|
|
|
- !test_bit(HCI_UNCONFIGURED, &d->dev_flags))
|
|
|
+ !hci_dev_test_flag(d, HCI_UNCONFIGURED))
|
|
|
count++;
|
|
|
}
|
|
|
|
|
@@ -390,9 +398,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
count = 0;
|
|
|
list_for_each_entry(d, &hci_dev_list, list) {
|
|
|
- if (test_bit(HCI_SETUP, &d->dev_flags) ||
|
|
|
- test_bit(HCI_CONFIG, &d->dev_flags) ||
|
|
|
- test_bit(HCI_USER_CHANNEL, &d->dev_flags))
|
|
|
+ if (hci_dev_test_flag(d, HCI_SETUP) ||
|
|
|
+ hci_dev_test_flag(d, HCI_CONFIG) ||
|
|
|
+ hci_dev_test_flag(d, HCI_USER_CHANNEL))
|
|
|
continue;
|
|
|
|
|
|
/* Devices marked as raw-only are neither configured
|
|
@@ -402,7 +410,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
continue;
|
|
|
|
|
|
if (d->dev_type == HCI_BREDR &&
|
|
|
- !test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
|
|
|
+ !hci_dev_test_flag(d, HCI_UNCONFIGURED)) {
|
|
|
rp->index[count++] = cpu_to_le16(d->id);
|
|
|
BT_DBG("Added hci%u", d->id);
|
|
|
}
|
|
@@ -413,8 +421,8 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
read_unlock(&hci_dev_list_lock);
|
|
|
|
|
|
- err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
|
|
|
- rp_len);
|
|
|
+ err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST,
|
|
|
+ 0, rp, rp_len);
|
|
|
|
|
|
kfree(rp);
|
|
|
|
|
@@ -437,7 +445,7 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
|
|
|
count = 0;
|
|
|
list_for_each_entry(d, &hci_dev_list, list) {
|
|
|
if (d->dev_type == HCI_BREDR &&
|
|
|
- test_bit(HCI_UNCONFIGURED, &d->dev_flags))
|
|
|
+ hci_dev_test_flag(d, HCI_UNCONFIGURED))
|
|
|
count++;
|
|
|
}
|
|
|
|
|
@@ -450,9 +458,9 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
count = 0;
|
|
|
list_for_each_entry(d, &hci_dev_list, list) {
|
|
|
- if (test_bit(HCI_SETUP, &d->dev_flags) ||
|
|
|
- test_bit(HCI_CONFIG, &d->dev_flags) ||
|
|
|
- test_bit(HCI_USER_CHANNEL, &d->dev_flags))
|
|
|
+ if (hci_dev_test_flag(d, HCI_SETUP) ||
|
|
|
+ hci_dev_test_flag(d, HCI_CONFIG) ||
|
|
|
+ hci_dev_test_flag(d, HCI_USER_CHANNEL))
|
|
|
continue;
|
|
|
|
|
|
/* Devices marked as raw-only are neither configured
|
|
@@ -462,7 +470,7 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
|
|
|
continue;
|
|
|
|
|
|
if (d->dev_type == HCI_BREDR &&
|
|
|
- test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
|
|
|
+ hci_dev_test_flag(d, HCI_UNCONFIGURED)) {
|
|
|
rp->index[count++] = cpu_to_le16(d->id);
|
|
|
BT_DBG("Added hci%u", d->id);
|
|
|
}
|
|
@@ -473,8 +481,8 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
read_unlock(&hci_dev_list_lock);
|
|
|
|
|
|
- err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_UNCONF_INDEX_LIST,
|
|
|
- 0, rp, rp_len);
|
|
|
+ err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE,
|
|
|
+ MGMT_OP_READ_UNCONF_INDEX_LIST, 0, rp, rp_len);
|
|
|
|
|
|
kfree(rp);
|
|
|
|
|
@@ -484,7 +492,7 @@ static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
|
|
|
static bool is_configured(struct hci_dev *hdev)
|
|
|
{
|
|
|
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
|
|
|
- !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
|
|
|
+ !hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
|
|
|
return false;
|
|
|
|
|
|
if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
|
|
@@ -499,7 +507,7 @@ static __le32 get_missing_options(struct hci_dev *hdev)
|
|
|
u32 options = 0;
|
|
|
|
|
|
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) &&
|
|
|
- !test_bit(HCI_EXT_CONFIGURED, &hdev->dev_flags))
|
|
|
+ !hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
|
|
|
options |= MGMT_OPTION_EXTERNAL_CONFIG;
|
|
|
|
|
|
if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
|
|
@@ -521,8 +529,8 @@ static int send_options_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
|
|
|
{
|
|
|
__le32 options = get_missing_options(hdev);
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, opcode, 0, &options,
|
|
|
- sizeof(options));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, opcode, 0, &options,
|
|
|
+ sizeof(options));
|
|
|
}
|
|
|
|
|
|
static int read_config_info(struct sock *sk, struct hci_dev *hdev,
|
|
@@ -549,8 +557,8 @@ static int read_config_info(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, &rp,
|
|
|
- sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0,
|
|
|
+ &rp, sizeof(rp));
|
|
|
}
|
|
|
|
|
|
static u32 get_supported_settings(struct hci_dev *hdev)
|
|
@@ -583,6 +591,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
|
|
|
settings |= MGMT_SETTING_ADVERTISING;
|
|
|
settings |= MGMT_SETTING_SECURE_CONN;
|
|
|
settings |= MGMT_SETTING_PRIVACY;
|
|
|
+ settings |= MGMT_SETTING_STATIC_ADDRESS;
|
|
|
}
|
|
|
|
|
|
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
|
|
@@ -599,45 +608,64 @@ static u32 get_current_settings(struct hci_dev *hdev)
|
|
|
if (hdev_is_powered(hdev))
|
|
|
settings |= MGMT_SETTING_POWERED;
|
|
|
|
|
|
- if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_CONNECTABLE))
|
|
|
settings |= MGMT_SETTING_CONNECTABLE;
|
|
|
|
|
|
- if (test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
|
|
|
settings |= MGMT_SETTING_FAST_CONNECTABLE;
|
|
|
|
|
|
- if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
|
|
|
settings |= MGMT_SETTING_DISCOVERABLE;
|
|
|
|
|
|
- if (test_bit(HCI_BONDABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_BONDABLE))
|
|
|
settings |= MGMT_SETTING_BONDABLE;
|
|
|
|
|
|
- if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
settings |= MGMT_SETTING_BREDR;
|
|
|
|
|
|
- if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
settings |= MGMT_SETTING_LE;
|
|
|
|
|
|
- if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY))
|
|
|
settings |= MGMT_SETTING_LINK_SECURITY;
|
|
|
|
|
|
- if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
|
|
|
settings |= MGMT_SETTING_SSP;
|
|
|
|
|
|
- if (test_bit(HCI_HS_ENABLED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_HS_ENABLED))
|
|
|
settings |= MGMT_SETTING_HS;
|
|
|
|
|
|
- if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
|
|
settings |= MGMT_SETTING_ADVERTISING;
|
|
|
|
|
|
- if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SC_ENABLED))
|
|
|
settings |= MGMT_SETTING_SECURE_CONN;
|
|
|
|
|
|
- if (test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS))
|
|
|
settings |= MGMT_SETTING_DEBUG_KEYS;
|
|
|
|
|
|
- if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_PRIVACY))
|
|
|
settings |= MGMT_SETTING_PRIVACY;
|
|
|
|
|
|
+ /* The current setting for static address has two purposes. The
|
|
|
+ * first is to indicate if the static address will be used and
|
|
|
+ * the second is to indicate if it is actually set.
|
|
|
+ *
|
|
|
+ * This means if the static address is not configured, this flag
|
|
|
+ * will never bet set. If the address is configured, then if the
|
|
|
+ * address is actually used decides if the flag is set or not.
|
|
|
+ *
|
|
|
+ * For single mode LE only controllers and dual-mode controllers
|
|
|
+ * with BR/EDR disabled, the existence of the static address will
|
|
|
+ * be evaluated.
|
|
|
+ */
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
|
|
|
+ !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) ||
|
|
|
+ !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
|
|
|
+ if (bacmp(&hdev->static_addr, BDADDR_ANY))
|
|
|
+ settings |= MGMT_SETTING_STATIC_ADDRESS;
|
|
|
+ }
|
|
|
+
|
|
|
return settings;
|
|
|
}
|
|
|
|
|
@@ -751,9 +779,10 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
-static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
|
|
|
+static struct mgmt_pending_cmd *mgmt_pending_find(u16 opcode,
|
|
|
+ struct hci_dev *hdev)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
|
if (cmd->opcode == opcode)
|
|
@@ -763,11 +792,11 @@ static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static struct pending_cmd *mgmt_pending_find_data(u16 opcode,
|
|
|
- struct hci_dev *hdev,
|
|
|
- const void *data)
|
|
|
+static struct mgmt_pending_cmd *mgmt_pending_find_data(u16 opcode,
|
|
|
+ struct hci_dev *hdev,
|
|
|
+ const void *data)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
|
if (cmd->user_data != data)
|
|
@@ -811,7 +840,7 @@ static void update_scan_rsp_data(struct hci_request *req)
|
|
|
struct hci_cp_le_set_scan_rsp_data cp;
|
|
|
u8 len;
|
|
|
|
|
|
- if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
return;
|
|
|
|
|
|
memset(&cp, 0, sizeof(cp));
|
|
@@ -832,7 +861,7 @@ static void update_scan_rsp_data(struct hci_request *req)
|
|
|
|
|
|
static u8 get_adv_discov_flags(struct hci_dev *hdev)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
/* If there's a pending mgmt command the flags will not yet have
|
|
|
* their final values, so check for this first.
|
|
@@ -845,9 +874,9 @@ static u8 get_adv_discov_flags(struct hci_dev *hdev)
|
|
|
else if (cp->val == 0x02)
|
|
|
return LE_AD_LIMITED;
|
|
|
} else {
|
|
|
- if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
|
|
|
return LE_AD_LIMITED;
|
|
|
- else if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
|
|
|
+ else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
|
|
|
return LE_AD_GENERAL;
|
|
|
}
|
|
|
|
|
@@ -860,7 +889,7 @@ static u8 create_adv_data(struct hci_dev *hdev, u8 *ptr)
|
|
|
|
|
|
flags |= get_adv_discov_flags(hdev);
|
|
|
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
flags |= LE_AD_NO_BREDR;
|
|
|
|
|
|
if (flags) {
|
|
@@ -892,7 +921,7 @@ static void update_adv_data(struct hci_request *req)
|
|
|
struct hci_cp_le_set_adv_data cp;
|
|
|
u8 len;
|
|
|
|
|
|
- if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
return;
|
|
|
|
|
|
memset(&cp, 0, sizeof(cp));
|
|
@@ -980,10 +1009,10 @@ static void update_eir(struct hci_request *req)
|
|
|
if (!lmp_ext_inq_capable(hdev))
|
|
|
return;
|
|
|
|
|
|
- if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
|
|
|
return;
|
|
|
|
|
|
- if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
|
|
|
return;
|
|
|
|
|
|
memset(&cp, 0, sizeof(cp));
|
|
@@ -1019,17 +1048,17 @@ static void update_class(struct hci_request *req)
|
|
|
if (!hdev_is_powered(hdev))
|
|
|
return;
|
|
|
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
return;
|
|
|
|
|
|
- if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
|
|
|
return;
|
|
|
|
|
|
cod[0] = hdev->minor_class;
|
|
|
cod[1] = hdev->major_class;
|
|
|
cod[2] = get_service_classes(hdev);
|
|
|
|
|
|
- if (test_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
|
|
|
cod[1] |= 0x20;
|
|
|
|
|
|
if (memcmp(cod, hdev->dev_class, 3) == 0)
|
|
@@ -1040,7 +1069,7 @@ static void update_class(struct hci_request *req)
|
|
|
|
|
|
static bool get_connectable(struct hci_dev *hdev)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
/* If there's a pending mgmt command the flag will not yet have
|
|
|
* it's final value, so check for this first.
|
|
@@ -1051,7 +1080,7 @@ static bool get_connectable(struct hci_dev *hdev)
|
|
|
return cp->val;
|
|
|
}
|
|
|
|
|
|
- return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
|
|
|
+ return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
|
|
|
}
|
|
|
|
|
|
static void disable_advertising(struct hci_request *req)
|
|
@@ -1071,7 +1100,7 @@ static void enable_advertising(struct hci_request *req)
|
|
|
if (hci_conn_num(hdev, LE_LINK) > 0)
|
|
|
return;
|
|
|
|
|
|
- if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ADV))
|
|
|
disable_advertising(req);
|
|
|
|
|
|
/* Clear the HCI_LE_ADV bit temporarily so that the
|
|
@@ -1079,9 +1108,12 @@ static void enable_advertising(struct hci_request *req)
|
|
|
* and write a new random address. The flag will be set back on
|
|
|
* as soon as the SET_ADV_ENABLE HCI command completes.
|
|
|
*/
|
|
|
- clear_bit(HCI_LE_ADV, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
|
|
|
|
|
- connectable = get_connectable(hdev);
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
|
|
|
+ connectable = true;
|
|
|
+ else
|
|
|
+ connectable = get_connectable(hdev);
|
|
|
|
|
|
/* Set require_privacy to true only when non-connectable
|
|
|
* advertising is used. In that case it is fine to use a
|
|
@@ -1108,7 +1140,7 @@ static void service_cache_off(struct work_struct *work)
|
|
|
service_cache.work);
|
|
|
struct hci_request req;
|
|
|
|
|
|
- if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
|
|
|
return;
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
@@ -1131,9 +1163,9 @@ static void rpa_expired(struct work_struct *work)
|
|
|
|
|
|
BT_DBG("");
|
|
|
|
|
|
- set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
|
|
|
|
|
|
- if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
|
|
return;
|
|
|
|
|
|
/* The generation of a new RPA and programming it into the
|
|
@@ -1146,7 +1178,7 @@ static void rpa_expired(struct work_struct *work)
|
|
|
|
|
|
static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
|
|
|
{
|
|
|
- if (test_and_set_bit(HCI_MGMT, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_and_set_flag(hdev, HCI_MGMT))
|
|
|
return;
|
|
|
|
|
|
INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off);
|
|
@@ -1157,7 +1189,7 @@ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
|
|
|
* for mgmt we require user-space to explicitly enable
|
|
|
* it
|
|
|
*/
|
|
|
- clear_bit(HCI_BONDABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_BONDABLE);
|
|
|
}
|
|
|
|
|
|
static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
|
|
@@ -1186,22 +1218,22 @@ static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp,
|
|
|
- sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp,
|
|
|
+ sizeof(rp));
|
|
|
}
|
|
|
|
|
|
-static void mgmt_pending_free(struct pending_cmd *cmd)
|
|
|
+static void mgmt_pending_free(struct mgmt_pending_cmd *cmd)
|
|
|
{
|
|
|
sock_put(cmd->sk);
|
|
|
kfree(cmd->param);
|
|
|
kfree(cmd);
|
|
|
}
|
|
|
|
|
|
-static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|
|
- struct hci_dev *hdev, void *data,
|
|
|
- u16 len)
|
|
|
+static struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|
|
+ struct hci_dev *hdev,
|
|
|
+ void *data, u16 len)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
|
|
if (!cmd)
|
|
@@ -1227,11 +1259,11 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
|
|
|
}
|
|
|
|
|
|
static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
|
|
- void (*cb)(struct pending_cmd *cmd,
|
|
|
+ void (*cb)(struct mgmt_pending_cmd *cmd,
|
|
|
void *data),
|
|
|
void *data)
|
|
|
{
|
|
|
- struct pending_cmd *cmd, *tmp;
|
|
|
+ struct mgmt_pending_cmd *cmd, *tmp;
|
|
|
|
|
|
list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
|
|
|
if (opcode > 0 && cmd->opcode != opcode)
|
|
@@ -1241,7 +1273,7 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void mgmt_pending_remove(struct pending_cmd *cmd)
|
|
|
+static void mgmt_pending_remove(struct mgmt_pending_cmd *cmd)
|
|
|
{
|
|
|
list_del(&cmd->list);
|
|
|
mgmt_pending_free(cmd);
|
|
@@ -1251,8 +1283,8 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
|
|
|
{
|
|
|
__le32 settings = cpu_to_le32(get_current_settings(hdev));
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, opcode, 0, &settings,
|
|
|
- sizeof(settings));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, opcode, 0, &settings,
|
|
|
+ sizeof(settings));
|
|
|
}
|
|
|
|
|
|
static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
@@ -1296,7 +1328,7 @@ static bool hci_stop_discovery(struct hci_request *req)
|
|
|
|
|
|
default:
|
|
|
/* Passive scanning */
|
|
|
- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
|
|
|
hci_req_add_le_scan_disable(req);
|
|
|
return true;
|
|
|
}
|
|
@@ -1322,7 +1354,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
|
|
|
hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ADV))
|
|
|
disable_advertising(&req);
|
|
|
|
|
|
discov_stopped = hci_stop_discovery(&req);
|
|
@@ -1370,24 +1402,24 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
- if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
|
|
|
cancel_delayed_work(&hdev->power_off);
|
|
|
|
|
|
if (cp->val) {
|
|
@@ -1452,7 +1484,7 @@ struct cmd_lookup {
|
|
|
u8 mgmt_status;
|
|
|
};
|
|
|
|
|
|
-static void settings_rsp(struct pending_cmd *cmd, void *data)
|
|
|
+static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
struct cmd_lookup *match = data;
|
|
|
|
|
@@ -1468,15 +1500,15 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
|
|
|
mgmt_pending_free(cmd);
|
|
|
}
|
|
|
|
|
|
-static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
|
|
|
+static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
u8 *status = data;
|
|
|
|
|
|
- cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
|
|
|
+ mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
|
|
|
mgmt_pending_remove(cmd);
|
|
|
}
|
|
|
|
|
|
-static void cmd_complete_rsp(struct pending_cmd *cmd, void *data)
|
|
|
+static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
if (cmd->cmd_complete) {
|
|
|
u8 *status = data;
|
|
@@ -1490,23 +1522,23 @@ static void cmd_complete_rsp(struct pending_cmd *cmd, void *data)
|
|
|
cmd_status_rsp(cmd, data);
|
|
|
}
|
|
|
|
|
|
-static int generic_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
|
{
|
|
|
- return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
|
- cmd->param, cmd->param_len);
|
|
|
+ return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
|
+ cmd->param, cmd->param_len);
|
|
|
}
|
|
|
|
|
|
-static int addr_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
|
{
|
|
|
- return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, cmd->param,
|
|
|
- sizeof(struct mgmt_addr_info));
|
|
|
+ return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
|
+ cmd->param, sizeof(struct mgmt_addr_info));
|
|
|
}
|
|
|
|
|
|
static u8 mgmt_bredr_support(struct hci_dev *hdev)
|
|
|
{
|
|
|
if (!lmp_bredr_capable(hdev))
|
|
|
return MGMT_STATUS_NOT_SUPPORTED;
|
|
|
- else if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ else if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
return MGMT_STATUS_REJECTED;
|
|
|
else
|
|
|
return MGMT_STATUS_SUCCESS;
|
|
@@ -1516,7 +1548,7 @@ static u8 mgmt_le_support(struct hci_dev *hdev)
|
|
|
{
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
return MGMT_STATUS_NOT_SUPPORTED;
|
|
|
- else if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
+ else if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
return MGMT_STATUS_REJECTED;
|
|
|
else
|
|
|
return MGMT_STATUS_SUCCESS;
|
|
@@ -1525,7 +1557,7 @@ static u8 mgmt_le_support(struct hci_dev *hdev)
|
|
|
static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
|
|
|
u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct mgmt_mode *cp;
|
|
|
struct hci_request req;
|
|
|
bool changed;
|
|
@@ -1540,15 +1572,14 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
|
|
|
|
|
|
if (status) {
|
|
|
u8 mgmt_err = mgmt_status(status);
|
|
|
- cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
- clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
goto remove_cmd;
|
|
|
}
|
|
|
|
|
|
cp = cmd->param;
|
|
|
if (cp->val) {
|
|
|
- changed = !test_and_set_bit(HCI_DISCOVERABLE,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_DISCOVERABLE);
|
|
|
|
|
|
if (hdev->discov_timeout > 0) {
|
|
|
int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
|
|
@@ -1556,8 +1587,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
|
|
|
to);
|
|
|
}
|
|
|
} else {
|
|
|
- changed = test_and_clear_bit(HCI_DISCOVERABLE,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_DISCOVERABLE);
|
|
|
}
|
|
|
|
|
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_DISCOVERABLE, hdev);
|
|
@@ -1586,7 +1616,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_set_discoverable *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
u16 timeout;
|
|
|
u8 scan;
|
|
@@ -1594,14 +1624,14 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
- if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
|
|
|
- !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
|
|
|
+ !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
timeout = __le16_to_cpu(cp->timeout);
|
|
|
|
|
@@ -1610,27 +1640,27 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
*/
|
|
|
if ((cp->val == 0x00 && timeout > 0) ||
|
|
|
(cp->val == 0x02 && timeout == 0))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev) && timeout > 0) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_NOT_POWERED);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
|
|
|
mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
- if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_CONNECTABLE)) {
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -1641,8 +1671,8 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
* not a valid operation since it requires a timeout
|
|
|
* and so no need to check HCI_LIMITED_DISCOVERABLE.
|
|
|
*/
|
|
|
- if (!!cp->val != test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) {
|
|
|
- change_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ if (!!cp->val != hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) {
|
|
|
+ hci_dev_change_flag(hdev, HCI_DISCOVERABLE);
|
|
|
changed = true;
|
|
|
}
|
|
|
|
|
@@ -1660,9 +1690,9 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
* value with the new value. And if only the timeout gets updated,
|
|
|
* then no need for any HCI transactions.
|
|
|
*/
|
|
|
- if (!!cp->val == test_bit(HCI_DISCOVERABLE, &hdev->dev_flags) &&
|
|
|
- (cp->val == 0x02) == test_bit(HCI_LIMITED_DISCOVERABLE,
|
|
|
- &hdev->dev_flags)) {
|
|
|
+ if (!!cp->val == hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
|
|
|
+ (cp->val == 0x02) == hci_dev_test_flag(hdev,
|
|
|
+ HCI_LIMITED_DISCOVERABLE)) {
|
|
|
cancel_delayed_work(&hdev->discov_off);
|
|
|
hdev->discov_timeout = timeout;
|
|
|
|
|
@@ -1691,16 +1721,16 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
/* Limited discoverable mode */
|
|
|
if (cp->val == 0x02)
|
|
|
- set_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
else
|
|
|
- clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
/* The procedure for LE-only controllers is much simpler - just
|
|
|
* update the advertising data.
|
|
|
*/
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
goto update_ad;
|
|
|
|
|
|
scan = SCAN_PAGE;
|
|
@@ -1730,7 +1760,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
scan |= SCAN_INQUIRY;
|
|
|
} else {
|
|
|
- clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
}
|
|
|
|
|
|
hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
|
|
@@ -1753,7 +1783,7 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
|
|
|
struct hci_cp_write_page_scan_activity acp;
|
|
|
u8 type;
|
|
|
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
return;
|
|
|
|
|
|
if (hdev->hci_ver < BLUETOOTH_VER_1_2)
|
|
@@ -1785,7 +1815,7 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
|
|
|
static void set_connectable_complete(struct hci_dev *hdev, u8 status,
|
|
|
u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct mgmt_mode *cp;
|
|
|
bool conn_changed, discov_changed;
|
|
|
|
|
@@ -1799,20 +1829,20 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status,
|
|
|
|
|
|
if (status) {
|
|
|
u8 mgmt_err = mgmt_status(status);
|
|
|
- cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
+ mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
goto remove_cmd;
|
|
|
}
|
|
|
|
|
|
cp = cmd->param;
|
|
|
if (cp->val) {
|
|
|
- conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
|
|
|
- &hdev->dev_flags);
|
|
|
+ conn_changed = !hci_dev_test_and_set_flag(hdev,
|
|
|
+ HCI_CONNECTABLE);
|
|
|
discov_changed = false;
|
|
|
} else {
|
|
|
- conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
|
|
|
- &hdev->dev_flags);
|
|
|
- discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
|
|
|
- &hdev->dev_flags);
|
|
|
+ conn_changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_CONNECTABLE);
|
|
|
+ discov_changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_DISCOVERABLE);
|
|
|
}
|
|
|
|
|
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
|
|
@@ -1838,14 +1868,14 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
|
|
|
bool changed = false;
|
|
|
int err;
|
|
|
|
|
|
- if (!!val != test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
|
|
|
+ if (!!val != hci_dev_test_flag(hdev, HCI_CONNECTABLE))
|
|
|
changed = true;
|
|
|
|
|
|
if (val) {
|
|
|
- set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_CONNECTABLE);
|
|
|
} else {
|
|
|
- clear_bit(HCI_CONNECTABLE, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_CONNECTABLE);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev);
|
|
@@ -1865,21 +1895,21 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
u8 scan;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
- if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
|
|
|
- !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
|
|
|
+ !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -1890,8 +1920,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
|
|
|
mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -1907,10 +1937,10 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
* by-product of disabling connectable, we need to update the
|
|
|
* advertising flags.
|
|
|
*/
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
|
|
if (!cp->val) {
|
|
|
- clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
|
|
|
}
|
|
|
update_adv_data(&req);
|
|
|
} else if (cp->val != test_bit(HCI_PSCAN, &hdev->flags)) {
|
|
@@ -1939,17 +1969,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
}
|
|
|
|
|
|
no_scan_update:
|
|
|
- /* If we're going from non-connectable to connectable or
|
|
|
- * vice-versa when fast connectable is enabled ensure that fast
|
|
|
- * connectable gets disabled. write_fast_connectable won't do
|
|
|
- * anything if the page scan parameters are already what they
|
|
|
- * should be.
|
|
|
- */
|
|
|
- if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
|
|
|
- write_fast_connectable(&req, false);
|
|
|
-
|
|
|
/* Update the advertising parameters if necessary */
|
|
|
- if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
|
|
enable_advertising(&req);
|
|
|
|
|
|
err = hci_req_run(&req, set_connectable_complete);
|
|
@@ -1976,15 +1997,15 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_BONDABLE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BONDABLE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (cp->val)
|
|
|
- changed = !test_and_set_bit(HCI_BONDABLE, &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_BONDABLE);
|
|
|
else
|
|
|
- changed = test_and_clear_bit(HCI_BONDABLE, &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_BONDABLE);
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_BONDABLE, hdev);
|
|
|
if (err < 0)
|
|
@@ -2002,7 +2023,7 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
u8 val, status;
|
|
|
int err;
|
|
|
|
|
@@ -2010,21 +2031,20 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
status = mgmt_bredr_support(hdev);
|
|
|
if (status)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
- status);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
+ status);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
bool changed = false;
|
|
|
|
|
|
- if (!!cp->val != test_bit(HCI_LINK_SECURITY,
|
|
|
- &hdev->dev_flags)) {
|
|
|
- change_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
|
|
|
+ if (!!cp->val != hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
|
|
|
+ hci_dev_change_flag(hdev, HCI_LINK_SECURITY);
|
|
|
changed = true;
|
|
|
}
|
|
|
|
|
@@ -2039,8 +2059,8 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -2071,7 +2091,7 @@ failed:
|
|
|
static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
u8 status;
|
|
|
int err;
|
|
|
|
|
@@ -2079,15 +2099,15 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
|
|
|
status = mgmt_bredr_support(hdev);
|
|
|
if (status)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, status);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, status);
|
|
|
|
|
|
if (!lmp_ssp_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -2095,16 +2115,16 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
bool changed;
|
|
|
|
|
|
if (cp->val) {
|
|
|
- changed = !test_and_set_bit(HCI_SSP_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev,
|
|
|
+ HCI_SSP_ENABLED);
|
|
|
} else {
|
|
|
- changed = test_and_clear_bit(HCI_SSP_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_SSP_ENABLED);
|
|
|
if (!changed)
|
|
|
- changed = test_and_clear_bit(HCI_HS_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_HS_ENABLED);
|
|
|
else
|
|
|
- clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
|
|
@@ -2118,12 +2138,12 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
- if (!!cp->val == test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (!!cp->val == hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
|
|
|
goto failed;
|
|
|
}
|
|
@@ -2134,7 +2154,7 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
- if (!cp->val && test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
|
|
|
+ if (!cp->val && hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
|
|
|
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
|
|
|
sizeof(cp->val), &cp->val);
|
|
|
|
|
@@ -2160,38 +2180,38 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
|
|
|
status = mgmt_bredr_support(hdev);
|
|
|
if (status)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS, status);
|
|
|
|
|
|
if (!lmp_ssp_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
- if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (cp->val) {
|
|
|
- changed = !test_and_set_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_HS_ENABLED);
|
|
|
} else {
|
|
|
if (hdev_is_powered(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- changed = test_and_clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_HS_ENABLED);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_HS, hdev);
|
|
@@ -2232,7 +2252,7 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
* has actually been enabled. During power on, the
|
|
|
* update in powered_update_hci will take care of it.
|
|
|
*/
|
|
|
- if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
|
|
|
struct hci_request req;
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
@@ -2250,7 +2270,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
struct hci_cp_write_le_host_supported hci_cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
u8 val, enabled;
|
|
@@ -2258,17 +2278,17 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
/* LE-only devices do not allow toggling LE on/off */
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -2278,13 +2298,13 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
if (!hdev_is_powered(hdev) || val == enabled) {
|
|
|
bool changed = false;
|
|
|
|
|
|
- if (val != test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
|
|
|
- change_bit(HCI_LE_ENABLED, &hdev->dev_flags);
|
|
|
+ if (val != hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
|
|
|
+ hci_dev_change_flag(hdev, HCI_LE_ENABLED);
|
|
|
changed = true;
|
|
|
}
|
|
|
|
|
|
- if (!val && test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
|
|
|
- clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
|
|
+ if (!val && hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
|
|
|
+ hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
|
|
changed = true;
|
|
|
}
|
|
|
|
|
@@ -2300,8 +2320,8 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_LE, hdev) ||
|
|
|
mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2319,7 +2339,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
hci_cp.le = val;
|
|
|
hci_cp.simul = 0x00;
|
|
|
} else {
|
|
|
- if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ADV))
|
|
|
disable_advertising(&req);
|
|
|
}
|
|
|
|
|
@@ -2343,7 +2363,7 @@ unlock:
|
|
|
*/
|
|
|
static bool pending_eir_or_class(struct hci_dev *hdev)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
|
switch (cmd->opcode) {
|
|
@@ -2379,7 +2399,7 @@ static u8 get_uuid_size(const u8 *uuid)
|
|
|
|
|
|
static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -2387,8 +2407,8 @@ static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status)
|
|
|
if (!cmd)
|
|
|
goto unlock;
|
|
|
|
|
|
- cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
|
|
|
- hdev->dev_class, 3);
|
|
|
+ mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
|
|
|
+ mgmt_status(status), hdev->dev_class, 3);
|
|
|
|
|
|
mgmt_pending_remove(cmd);
|
|
|
|
|
@@ -2406,7 +2426,7 @@ static void add_uuid_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_add_uuid *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
struct bt_uuid *uuid;
|
|
|
int err;
|
|
@@ -2416,8 +2436,8 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (pending_eir_or_class(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -2443,8 +2463,8 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
if (err != -ENODATA)
|
|
|
goto failed;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0,
|
|
|
- hdev->dev_class, 3);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0,
|
|
|
+ hdev->dev_class, 3);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -2466,7 +2486,7 @@ static bool enable_service_cache(struct hci_dev *hdev)
|
|
|
if (!hdev_is_powered(hdev))
|
|
|
return false;
|
|
|
|
|
|
- if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
|
|
|
+ if (!hci_dev_test_and_set_flag(hdev, HCI_SERVICE_CACHE)) {
|
|
|
queue_delayed_work(hdev->workqueue, &hdev->service_cache,
|
|
|
CACHE_TIMEOUT);
|
|
|
return true;
|
|
@@ -2486,7 +2506,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_remove_uuid *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct bt_uuid *match, *tmp;
|
|
|
u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
struct hci_request req;
|
|
@@ -2497,8 +2517,8 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (pending_eir_or_class(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2506,8 +2526,9 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_uuids_clear(hdev);
|
|
|
|
|
|
if (enable_service_cache(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID,
|
|
|
- 0, hdev->dev_class, 3);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_REMOVE_UUID,
|
|
|
+ 0, hdev->dev_class, 3);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2526,8 +2547,8 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
}
|
|
|
|
|
|
if (found == 0) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2542,8 +2563,8 @@ update_class:
|
|
|
if (err != -ENODATA)
|
|
|
goto unlock;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0,
|
|
|
- hdev->dev_class, 3);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0,
|
|
|
+ hdev->dev_class, 3);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2571,27 +2592,27 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_set_dev_class *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_bredr_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (pending_eir_or_class(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2599,14 +2620,14 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hdev->minor_class = cp->minor;
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
|
|
|
- hdev->dev_class, 3);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
|
|
|
+ hdev->dev_class, 3);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
- if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE)) {
|
|
|
hci_dev_unlock(hdev);
|
|
|
cancel_delayed_work_sync(&hdev->service_cache);
|
|
|
hci_dev_lock(hdev);
|
|
@@ -2620,8 +2641,8 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
if (err != -ENODATA)
|
|
|
goto unlock;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
|
|
|
- hdev->dev_class, 3);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
|
|
|
+ hdev->dev_class, 3);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2651,15 +2672,15 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_bredr_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
key_count = __le16_to_cpu(cp->key_count);
|
|
|
if (key_count > max_key_count) {
|
|
|
BT_ERR("load_link_keys: too big key_count value %u",
|
|
|
key_count);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
expected_len = sizeof(*cp) + key_count *
|
|
@@ -2667,13 +2688,13 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
if (expected_len != len) {
|
|
|
BT_ERR("load_link_keys: expected %u bytes, got %u bytes",
|
|
|
expected_len, len);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
if (cp->debug_keys != 0x00 && cp->debug_keys != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys,
|
|
|
key_count);
|
|
@@ -2682,8 +2703,9 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
struct mgmt_link_key_info *key = &cp->keys[i];
|
|
|
|
|
|
if (key->addr.type != BDADDR_BREDR || key->type > 0x08)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id,
|
|
|
+ MGMT_OP_LOAD_LINK_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
@@ -2691,11 +2713,10 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_link_keys_clear(hdev);
|
|
|
|
|
|
if (cp->debug_keys)
|
|
|
- changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_KEEP_DEBUG_KEYS);
|
|
|
else
|
|
|
- changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_KEEP_DEBUG_KEYS);
|
|
|
|
|
|
if (changed)
|
|
|
new_settings(hdev, NULL);
|
|
@@ -2713,7 +2734,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
key->type, key->pin_len, NULL);
|
|
|
}
|
|
|
|
|
|
- cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
|
|
|
+ mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
@@ -2738,7 +2759,7 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
struct mgmt_cp_unpair_device *cp = data;
|
|
|
struct mgmt_rp_unpair_device rp;
|
|
|
struct hci_cp_disconnect dc;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
|
|
|
@@ -2747,20 +2768,21 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.addr.type = cp->addr.type;
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
if (cp->disconnect != 0x00 && cp->disconnect != 0x01)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
- MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
+ MGMT_STATUS_NOT_POWERED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2810,8 +2832,9 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
}
|
|
|
|
|
|
if (err < 0) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
- MGMT_STATUS_NOT_PAIRED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
|
|
|
+ MGMT_STATUS_NOT_PAIRED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2819,8 +2842,8 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
* link is requested.
|
|
|
*/
|
|
|
if (!conn) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0,
|
|
|
+ &rp, sizeof(rp));
|
|
|
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
|
|
|
goto unlock;
|
|
|
}
|
|
@@ -2850,7 +2873,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
{
|
|
|
struct mgmt_cp_disconnect *cp = data;
|
|
|
struct mgmt_rp_disconnect rp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
|
|
|
@@ -2861,21 +2884,22 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.addr.type = cp->addr.type;
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!test_bit(HCI_UP, &hdev->flags)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
- MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
+ MGMT_STATUS_NOT_POWERED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
- MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
+ MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -2886,8 +2910,9 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
|
|
|
|
|
|
if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
- MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
|
|
|
+ MGMT_STATUS_NOT_CONNECTED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -2941,8 +2966,8 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS,
|
|
|
+ MGMT_STATUS_NOT_POWERED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -2975,8 +3000,8 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
/* Recalculate length in case of filtered SCO connections, etc */
|
|
|
rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp,
|
|
|
- rp_len);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp,
|
|
|
+ rp_len);
|
|
|
|
|
|
kfree(rp);
|
|
|
|
|
@@ -2988,7 +3013,7 @@ unlock:
|
|
|
static int send_pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev,
|
|
|
struct mgmt_cp_pin_code_neg_reply *cp)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
int err;
|
|
|
|
|
|
cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp,
|
|
@@ -3010,7 +3035,7 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
struct hci_conn *conn;
|
|
|
struct mgmt_cp_pin_code_reply *cp = data;
|
|
|
struct hci_cp_pin_code_reply reply;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("");
|
|
@@ -3018,15 +3043,15 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
+ MGMT_STATUS_NOT_POWERED);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
|
|
|
if (!conn) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
- MGMT_STATUS_NOT_CONNECTED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
+ MGMT_STATUS_NOT_CONNECTED);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -3039,8 +3064,8 @@ static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
err = send_pin_code_neg_reply(sk, hdev, &ncp);
|
|
|
if (err >= 0)
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
goto failed;
|
|
|
}
|
|
@@ -3074,8 +3099,8 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("");
|
|
|
|
|
|
if (cp->io_capability > SMP_IO_KEYBOARD_DISPLAY)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, NULL, 0);
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS, NULL, 0);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -3086,14 +3111,14 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0, NULL,
|
|
|
- 0);
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0,
|
|
|
+ NULL, 0);
|
|
|
}
|
|
|
|
|
|
-static struct pending_cmd *find_pairing(struct hci_conn *conn)
|
|
|
+static struct mgmt_pending_cmd *find_pairing(struct hci_conn *conn)
|
|
|
{
|
|
|
struct hci_dev *hdev = conn->hdev;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
|
|
|
if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
|
|
@@ -3108,7 +3133,7 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static int pairing_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
|
{
|
|
|
struct mgmt_rp_pair_device rp;
|
|
|
struct hci_conn *conn = cmd->user_data;
|
|
@@ -3117,8 +3142,8 @@ static int pairing_complete(struct pending_cmd *cmd, u8 status)
|
|
|
bacpy(&rp.addr.bdaddr, &conn->dst);
|
|
|
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
|
|
|
|
|
|
- err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE,
|
|
|
+ status, &rp, sizeof(rp));
|
|
|
|
|
|
/* So we don't get further callbacks for this connection */
|
|
|
conn->connect_cfm_cb = NULL;
|
|
@@ -3140,7 +3165,7 @@ static int pairing_complete(struct pending_cmd *cmd, u8 status)
|
|
|
void mgmt_smp_complete(struct hci_conn *conn, bool complete)
|
|
|
{
|
|
|
u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
cmd = find_pairing(conn);
|
|
|
if (cmd) {
|
|
@@ -3151,7 +3176,7 @@ void mgmt_smp_complete(struct hci_conn *conn, bool complete)
|
|
|
|
|
|
static void pairing_complete_cb(struct hci_conn *conn, u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status %u", status);
|
|
|
|
|
@@ -3167,7 +3192,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
|
|
|
|
|
|
static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status %u", status);
|
|
|
|
|
@@ -3189,7 +3214,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
{
|
|
|
struct mgmt_cp_pair_device *cp = data;
|
|
|
struct mgmt_rp_pair_device rp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
u8 sec_level, auth_type;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
@@ -3201,20 +3226,28 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.addr.type = cp->addr.type;
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
if (cp->io_cap > SMP_IO_KEYBOARD_DISPLAY)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_NOT_POWERED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
+ goto unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hci_bdaddr_is_paired(hdev, &cp->addr.bdaddr, cp->addr.type)) {
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_ALREADY_PAIRED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -3262,16 +3295,15 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
else
|
|
|
status = MGMT_STATUS_CONNECT_FAILED;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
- status, &rp,
|
|
|
- sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ status, &rp, sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (conn->connect_cfm_cb) {
|
|
|
hci_conn_drop(conn);
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -3315,7 +3347,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_addr_info *addr = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
|
|
|
@@ -3324,31 +3356,31 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_NOT_POWERED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
|
|
|
if (!cmd) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
conn = cmd->user_data;
|
|
|
|
|
|
if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
cmd->cmd_complete(cmd, MGMT_STATUS_CANCELLED);
|
|
|
mgmt_pending_remove(cmd);
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0,
|
|
|
- addr, sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0,
|
|
|
+ addr, sizeof(*addr));
|
|
|
unlock:
|
|
|
hci_dev_unlock(hdev);
|
|
|
return err;
|
|
@@ -3358,16 +3390,16 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
|
|
|
struct mgmt_addr_info *addr, u16 mgmt_op,
|
|
|
u16 hci_op, __le32 passkey)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
- MGMT_STATUS_NOT_POWERED, addr,
|
|
|
- sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
+ MGMT_STATUS_NOT_POWERED, addr,
|
|
|
+ sizeof(*addr));
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
@@ -3377,22 +3409,22 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
|
|
|
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &addr->bdaddr);
|
|
|
|
|
|
if (!conn) {
|
|
|
- err = cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
- MGMT_STATUS_NOT_CONNECTED, addr,
|
|
|
- sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
+ MGMT_STATUS_NOT_CONNECTED, addr,
|
|
|
+ sizeof(*addr));
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
|
|
|
err = smp_user_confirm_reply(conn, mgmt_op, passkey);
|
|
|
if (!err)
|
|
|
- err = cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
- MGMT_STATUS_SUCCESS, addr,
|
|
|
- sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
+ MGMT_STATUS_SUCCESS, addr,
|
|
|
+ sizeof(*addr));
|
|
|
else
|
|
|
- err = cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
- MGMT_STATUS_FAILED, addr,
|
|
|
- sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, mgmt_op,
|
|
|
+ MGMT_STATUS_FAILED, addr,
|
|
|
+ sizeof(*addr));
|
|
|
|
|
|
goto done;
|
|
|
}
|
|
@@ -3444,8 +3476,8 @@ static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("");
|
|
|
|
|
|
if (len != sizeof(*cp))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
return user_pairing_resp(sk, hdev, &cp->addr,
|
|
|
MGMT_OP_USER_CONFIRM_REPLY,
|
|
@@ -3501,7 +3533,7 @@ static void update_name(struct hci_request *req)
|
|
|
static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
struct mgmt_cp_set_local_name *cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status 0x%02x", status);
|
|
|
|
|
@@ -3514,11 +3546,11 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
cp = cmd->param;
|
|
|
|
|
|
if (status)
|
|
|
- cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
|
|
- mgmt_status(status));
|
|
|
+ mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
|
|
|
+ mgmt_status(status));
|
|
|
else
|
|
|
- cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
- cp, sizeof(*cp));
|
|
|
+ mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
+ cp, sizeof(*cp));
|
|
|
|
|
|
mgmt_pending_remove(cmd);
|
|
|
|
|
@@ -3530,7 +3562,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_set_local_name *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
@@ -3544,8 +3576,8 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
if (!memcmp(hdev->dev_name, cp->name, sizeof(hdev->dev_name)) &&
|
|
|
!memcmp(hdev->short_name, cp->short_name,
|
|
|
sizeof(hdev->short_name))) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
- data, len);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
+ data, len);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -3554,8 +3586,8 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name));
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
- data, len);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
|
|
|
+ data, len);
|
|
|
if (err < 0)
|
|
|
goto failed;
|
|
|
|
|
@@ -3598,7 +3630,7 @@ failed:
|
|
|
static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 data_len)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("%s", hdev->name);
|
|
@@ -3606,20 +3638,20 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
+ MGMT_STATUS_NOT_POWERED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (!lmp_ssp_capable(hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -3652,9 +3684,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s ", hdev->name);
|
|
|
|
|
|
if (!bdaddr_type_is_valid(addr->type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, addr,
|
|
|
- sizeof(*addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ addr, sizeof(*addr));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -3663,10 +3696,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
u8 status;
|
|
|
|
|
|
if (cp->addr.type != BDADDR_BREDR) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -3678,8 +3711,9 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
else
|
|
|
status = MGMT_STATUS_SUCCESS;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- status, &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_ADD_REMOTE_OOB_DATA, status,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
} else if (len == MGMT_ADD_REMOTE_OOB_EXT_DATA_SIZE) {
|
|
|
struct mgmt_cp_add_remote_oob_ext_data *cp = data;
|
|
|
u8 *rand192, *hash192, *rand256, *hash256;
|
|
@@ -3691,10 +3725,10 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
*/
|
|
|
if (memcmp(cp->rand192, ZERO_KEY, 16) ||
|
|
|
memcmp(cp->hash192, ZERO_KEY, 16)) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- addr, sizeof(*addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ addr, sizeof(*addr));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -3734,12 +3768,13 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
else
|
|
|
status = MGMT_STATUS_SUCCESS;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- status, &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
+ status, &cp->addr, sizeof(cp->addr));
|
|
|
} else {
|
|
|
BT_ERR("add_remote_oob_data: invalid length of %u bytes", len);
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
unlock:
|
|
@@ -3757,9 +3792,10 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (cp->addr.type != BDADDR_BREDR)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_REMOVE_REMOTE_OOB_DATA,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -3776,8 +3812,8 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
|
|
|
status = MGMT_STATUS_SUCCESS;
|
|
|
|
|
|
done:
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
|
|
|
- status, &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
|
|
|
+ status, &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
return err;
|
|
@@ -3820,12 +3856,12 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
|
|
|
return false;
|
|
|
|
|
|
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
|
|
|
- !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
|
|
|
+ !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
|
|
*status = MGMT_STATUS_NOT_SUPPORTED;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
|
|
|
/* Don't let discovery abort an outgoing
|
|
|
* connection attempt that's using directed
|
|
|
* advertising.
|
|
@@ -3843,7 +3879,7 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
|
|
|
* is running. Thus, we should temporarily stop it in order to
|
|
|
* set the discovery scanning parameters.
|
|
|
*/
|
|
|
- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
|
|
hci_req_add_le_scan_disable(req);
|
|
|
|
|
|
memset(¶m_cp, 0, sizeof(param_cp));
|
|
@@ -3883,7 +3919,7 @@ static bool trigger_discovery(struct hci_request *req, u8 *status)
|
|
|
static void start_discovery_complete(struct hci_dev *hdev, u8 status,
|
|
|
u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
unsigned long timeout;
|
|
|
|
|
|
BT_DBG("status %d", status);
|
|
@@ -3933,8 +3969,7 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status,
|
|
|
*/
|
|
|
if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
|
|
|
&hdev->quirks) &&
|
|
|
- (hdev->discovery.uuid_count > 0 ||
|
|
|
- hdev->discovery.rssi != HCI_RSSI_INVALID)) {
|
|
|
+ hdev->discovery.result_filtering) {
|
|
|
hdev->discovery.scan_start = jiffies;
|
|
|
hdev->discovery.scan_duration = timeout;
|
|
|
}
|
|
@@ -3951,7 +3986,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_start_discovery *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
u8 status;
|
|
|
int err;
|
|
@@ -3961,17 +3996,17 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
- MGMT_STATUS_NOT_POWERED,
|
|
|
- &cp->type, sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
+ MGMT_STATUS_NOT_POWERED,
|
|
|
+ &cp->type, sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
if (hdev->discovery.state != DISCOVERY_STOPPED ||
|
|
|
- test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
- MGMT_STATUS_BUSY, &cp->type,
|
|
|
- sizeof(cp->type));
|
|
|
+ hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) {
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
+ MGMT_STATUS_BUSY, &cp->type,
|
|
|
+ sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -3994,8 +4029,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
if (!trigger_discovery(&req, &status)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
- status, &cp->type, sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_START_DISCOVERY,
|
|
|
+ status, &cp->type, sizeof(cp->type));
|
|
|
mgmt_pending_remove(cmd);
|
|
|
goto failed;
|
|
|
}
|
|
@@ -4013,17 +4048,18 @@ failed:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static int service_discovery_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int service_discovery_cmd_complete(struct mgmt_pending_cmd *cmd,
|
|
|
+ u8 status)
|
|
|
{
|
|
|
- return cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
|
- cmd->param, 1);
|
|
|
+ return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
|
|
|
+ cmd->param, 1);
|
|
|
}
|
|
|
|
|
|
static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_start_service_discovery *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
const u16 max_uuid_count = ((U16_MAX - sizeof(*cp)) / 16);
|
|
|
u16 uuid_count, expected_len;
|
|
@@ -4035,19 +4071,19 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- MGMT_STATUS_NOT_POWERED,
|
|
|
- &cp->type, sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ MGMT_STATUS_NOT_POWERED,
|
|
|
+ &cp->type, sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
if (hdev->discovery.state != DISCOVERY_STOPPED ||
|
|
|
- test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags)) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- MGMT_STATUS_BUSY, &cp->type,
|
|
|
- sizeof(cp->type));
|
|
|
+ hci_dev_test_flag(hdev, HCI_PERIODIC_INQ)) {
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ MGMT_STATUS_BUSY, &cp->type,
|
|
|
+ sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -4055,10 +4091,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
if (uuid_count > max_uuid_count) {
|
|
|
BT_ERR("service_discovery: too big uuid_count value %u",
|
|
|
uuid_count);
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, &cp->type,
|
|
|
- sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS, &cp->type,
|
|
|
+ sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -4066,10 +4102,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
if (expected_len != len) {
|
|
|
BT_ERR("service_discovery: expected %u bytes, got %u bytes",
|
|
|
expected_len, len);
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, &cp->type,
|
|
|
- sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS, &cp->type,
|
|
|
+ sizeof(cp->type));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -4087,6 +4123,7 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
*/
|
|
|
hci_discovery_filter_clear(hdev);
|
|
|
|
|
|
+ hdev->discovery.result_filtering = true;
|
|
|
hdev->discovery.type = cp->type;
|
|
|
hdev->discovery.rssi = cp->rssi;
|
|
|
hdev->discovery.uuid_count = uuid_count;
|
|
@@ -4095,10 +4132,10 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
hdev->discovery.uuids = kmemdup(cp->uuids, uuid_count * 16,
|
|
|
GFP_KERNEL);
|
|
|
if (!hdev->discovery.uuids) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- MGMT_STATUS_FAILED,
|
|
|
- &cp->type, sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ MGMT_STATUS_FAILED,
|
|
|
+ &cp->type, sizeof(cp->type));
|
|
|
mgmt_pending_remove(cmd);
|
|
|
goto failed;
|
|
|
}
|
|
@@ -4107,9 +4144,9 @@ static int start_service_discovery(struct sock *sk, struct hci_dev *hdev,
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
if (!trigger_discovery(&req, &status)) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
- status, &cp->type, sizeof(cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_START_SERVICE_DISCOVERY,
|
|
|
+ status, &cp->type, sizeof(cp->type));
|
|
|
mgmt_pending_remove(cmd);
|
|
|
goto failed;
|
|
|
}
|
|
@@ -4129,7 +4166,7 @@ failed:
|
|
|
|
|
|
static void stop_discovery_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status %d", status);
|
|
|
|
|
@@ -4151,7 +4188,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_stop_discovery *mgmt_cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
@@ -4160,16 +4197,16 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hci_discovery_active(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
|
|
|
- MGMT_STATUS_REJECTED, &mgmt_cp->type,
|
|
|
- sizeof(mgmt_cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
|
|
|
+ MGMT_STATUS_REJECTED, &mgmt_cp->type,
|
|
|
+ sizeof(mgmt_cp->type));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (hdev->discovery.type != mgmt_cp->type) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, &mgmt_cp->type,
|
|
|
- sizeof(mgmt_cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &mgmt_cp->type, sizeof(mgmt_cp->type));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -4195,8 +4232,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
/* If no HCI commands were sent we're done */
|
|
|
if (err == -ENODATA) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
|
|
|
- &mgmt_cp->type, sizeof(mgmt_cp->type));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
|
|
|
+ &mgmt_cp->type, sizeof(mgmt_cp->type));
|
|
|
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
|
|
|
}
|
|
|
|
|
@@ -4217,17 +4254,17 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hci_discovery_active(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
|
|
|
- MGMT_STATUS_FAILED, &cp->addr,
|
|
|
- sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
|
|
|
+ MGMT_STATUS_FAILED, &cp->addr,
|
|
|
+ sizeof(cp->addr));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr);
|
|
|
if (!e) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
|
|
|
- MGMT_STATUS_INVALID_PARAMS, &cp->addr,
|
|
|
- sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS, &cp->addr,
|
|
|
+ sizeof(cp->addr));
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
@@ -4239,8 +4276,8 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hci_inquiry_cache_update_resolve(hdev, e);
|
|
|
}
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, &cp->addr,
|
|
|
- sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
failed:
|
|
|
hci_dev_unlock(hdev);
|
|
@@ -4257,9 +4294,9 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -4275,8 +4312,8 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
status = MGMT_STATUS_SUCCESS;
|
|
|
|
|
|
done:
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
@@ -4293,9 +4330,9 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -4311,8 +4348,8 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
status = MGMT_STATUS_SUCCESS;
|
|
|
|
|
|
done:
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
@@ -4332,8 +4369,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
source = __le16_to_cpu(cp->source);
|
|
|
|
|
|
if (source > 0x0002)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DEVICE_ID,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEVICE_ID,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -4342,7 +4379,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
hdev->devid_product = __le16_to_cpu(cp->product);
|
|
|
hdev->devid_version = __le16_to_cpu(cp->version);
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0,
|
|
|
+ NULL, 0);
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
update_eir(&req);
|
|
@@ -4368,10 +4406,10 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status,
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
|
|
|
- set_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ADV))
|
|
|
+ hci_dev_set_flag(hdev, HCI_ADVERTISING);
|
|
|
else
|
|
|
- clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_ADVERTISING);
|
|
|
|
|
|
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
|
|
|
&match);
|
|
@@ -4389,41 +4427,48 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
- u8 val, enabled, status;
|
|
|
+ u8 val, status;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
status = mgmt_le_support(hdev);
|
|
|
if (status)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
- status);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
+ status);
|
|
|
|
|
|
- if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
val = !!cp->val;
|
|
|
- enabled = test_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
|
|
|
|
|
/* The following conditions are ones which mean that we should
|
|
|
* not do any HCI communication but directly send a mgmt
|
|
|
* response to user space (after toggling the flag if
|
|
|
* necessary).
|
|
|
*/
|
|
|
- if (!hdev_is_powered(hdev) || val == enabled ||
|
|
|
+ if (!hdev_is_powered(hdev) ||
|
|
|
+ (val == hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
|
|
|
+ (cp->val == 0x02) == hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) ||
|
|
|
hci_conn_num(hdev, LE_LINK) > 0 ||
|
|
|
- (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
|
|
|
+ (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
|
|
|
hdev->le_scan_type == LE_SCAN_ACTIVE)) {
|
|
|
- bool changed = false;
|
|
|
+ bool changed;
|
|
|
|
|
|
- if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
|
|
|
- change_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
|
|
- changed = true;
|
|
|
+ if (cp->val) {
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_ADVERTISING);
|
|
|
+ if (cp->val == 0x02)
|
|
|
+ hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
|
|
+ else
|
|
|
+ hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
|
|
+ } else {
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_ADVERTISING);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_ADVERTISING, hdev);
|
|
@@ -4438,8 +4483,8 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_ADVERTISING, hdev) ||
|
|
|
mgmt_pending_find(MGMT_OP_SET_LE, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -4451,6 +4496,11 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
+ if (cp->val == 0x02)
|
|
|
+ hci_dev_set_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
|
|
+ else
|
|
|
+ hci_dev_clear_flag(hdev, HCI_ADVERTISING_CONNECTABLE);
|
|
|
+
|
|
|
if (val)
|
|
|
enable_advertising(&req);
|
|
|
else
|
|
@@ -4474,34 +4524,38 @@ static int set_static_address(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
if (hdev_is_powered(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (bacmp(&cp->bdaddr, BDADDR_ANY)) {
|
|
|
if (!bacmp(&cp->bdaddr, BDADDR_NONE))
|
|
|
- return cmd_status(sk, hdev->id,
|
|
|
- MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id,
|
|
|
+ MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
/* Two most significant bits shall be set */
|
|
|
if ((cp->bdaddr.b[5] & 0xc0) != 0xc0)
|
|
|
- return cmd_status(sk, hdev->id,
|
|
|
- MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id,
|
|
|
+ MGMT_OP_SET_STATIC_ADDRESS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
bacpy(&hdev->static_addr, &cp->bdaddr);
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_STATIC_ADDRESS, 0, NULL, 0);
|
|
|
+ err = send_settings_rsp(sk, MGMT_OP_SET_STATIC_ADDRESS, hdev);
|
|
|
+ if (err < 0)
|
|
|
+ goto unlock;
|
|
|
|
|
|
- hci_dev_unlock(hdev);
|
|
|
+ err = new_settings(hdev, sk);
|
|
|
|
|
|
+unlock:
|
|
|
+ hci_dev_unlock(hdev);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -4515,36 +4569,37 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
interval = __le16_to_cpu(cp->interval);
|
|
|
|
|
|
if (interval < 0x0004 || interval > 0x4000)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
window = __le16_to_cpu(cp->window);
|
|
|
|
|
|
if (window < 0x0004 || window > 0x4000)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
if (window > interval)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
hdev->le_scan_interval = interval;
|
|
|
hdev->le_scan_window = window;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0,
|
|
|
+ NULL, 0);
|
|
|
|
|
|
/* If background scan is running, restart it so new parameters are
|
|
|
* loaded.
|
|
|
*/
|
|
|
- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
|
|
|
hdev->discovery.state == DISCOVERY_STOPPED) {
|
|
|
struct hci_request req;
|
|
|
|
|
@@ -4564,7 +4619,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
|
|
|
static void fast_connectable_complete(struct hci_dev *hdev, u8 status,
|
|
|
u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status 0x%02x", status);
|
|
|
|
|
@@ -4575,15 +4630,15 @@ static void fast_connectable_complete(struct hci_dev *hdev, u8 status,
|
|
|
goto unlock;
|
|
|
|
|
|
if (status) {
|
|
|
- cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- mgmt_status(status));
|
|
|
+ mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ mgmt_status(status));
|
|
|
} else {
|
|
|
struct mgmt_mode *cp = cmd->param;
|
|
|
|
|
|
if (cp->val)
|
|
|
- set_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_FAST_CONNECTABLE);
|
|
|
else
|
|
|
- clear_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_FAST_CONNECTABLE);
|
|
|
|
|
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_FAST_CONNECTABLE, hdev);
|
|
|
new_settings(hdev, cmd->sk);
|
|
@@ -4599,40 +4654,40 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) ||
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) ||
|
|
|
hdev->hci_ver < BLUETOOTH_VER_1_2)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
-
|
|
|
- if (!hdev_is_powered(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_NOT_POWERED);
|
|
|
-
|
|
|
- if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_FAST_CONNECTABLE, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
+ goto unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!!cp->val == hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE)) {
|
|
|
+ err = send_settings_rsp(sk, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ hdev);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- if (!!cp->val == test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) {
|
|
|
+ if (!hdev_is_powered(hdev)) {
|
|
|
+ hci_dev_change_flag(hdev, HCI_FAST_CONNECTABLE);
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
hdev);
|
|
|
+ new_settings(hdev, sk);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -4649,8 +4704,8 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
err = hci_req_run(&req, fast_connectable_complete);
|
|
|
if (err < 0) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
- MGMT_STATUS_FAILED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
|
|
|
+ MGMT_STATUS_FAILED);
|
|
|
mgmt_pending_remove(cmd);
|
|
|
}
|
|
|
|
|
@@ -4662,7 +4717,7 @@ unlock:
|
|
|
|
|
|
static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status 0x%02x", status);
|
|
|
|
|
@@ -4678,9 +4733,9 @@ static void set_bredr_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
/* We need to restore the flag if related HCI commands
|
|
|
* failed.
|
|
|
*/
|
|
|
- clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
|
|
|
|
|
|
- cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
+ mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
|
|
|
} else {
|
|
|
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
|
|
|
new_settings(hdev, cmd->sk);
|
|
@@ -4695,41 +4750,41 @@ unlock:
|
|
|
static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_bredr_capable(hdev) || !lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
- if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
- if (cp->val == test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (cp->val == hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_BREDR, hdev);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
if (!cp->val) {
|
|
|
- clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LINK_SECURITY);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_FAST_CONNECTABLE);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
|
|
|
}
|
|
|
|
|
|
- change_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_change_flag(hdev, HCI_BREDR_ENABLED);
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_BREDR, hdev);
|
|
|
if (err < 0)
|
|
@@ -4741,8 +4796,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
|
|
|
/* Reject disabling when powered on */
|
|
|
if (!cp->val) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
goto unlock;
|
|
|
} else {
|
|
|
/* When configuring a dual-mode controller to operate
|
|
@@ -4759,18 +4814,18 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
* switching BR/EDR back on when secure connections has been
|
|
|
* enabled is not a supported transaction.
|
|
|
*/
|
|
|
- if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
|
|
|
(bacmp(&hdev->static_addr, BDADDR_ANY) ||
|
|
|
- test_bit(HCI_SC_ENABLED, &hdev->dev_flags))) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ hci_dev_test_flag(hdev, HCI_SC_ENABLED))) {
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
goto unlock;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_BREDR, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_BREDR,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -4783,7 +4838,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|
|
/* We need to flip the bit already here so that update_adv_data
|
|
|
* generates the correct flags.
|
|
|
*/
|
|
|
- set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
@@ -4806,7 +4861,7 @@ unlock:
|
|
|
|
|
|
static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct mgmt_mode *cp;
|
|
|
|
|
|
BT_DBG("%s status %u", hdev->name, status);
|
|
@@ -4818,8 +4873,8 @@ static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
goto unlock;
|
|
|
|
|
|
if (status) {
|
|
|
- cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
|
- mgmt_status(status));
|
|
|
+ mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
|
|
|
+ mgmt_status(status));
|
|
|
goto remove;
|
|
|
}
|
|
|
|
|
@@ -4827,16 +4882,16 @@ static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
|
|
|
switch (cp->val) {
|
|
|
case 0x00:
|
|
|
- clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SC_ONLY);
|
|
|
break;
|
|
|
case 0x01:
|
|
|
- set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_SC_ENABLED);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SC_ONLY);
|
|
|
break;
|
|
|
case 0x02:
|
|
|
- set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
|
|
|
- set_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_SC_ENABLED);
|
|
|
+ hci_dev_set_flag(hdev, HCI_SC_ONLY);
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -4853,7 +4908,7 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_mode *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
u8 val;
|
|
|
int err;
|
|
@@ -4861,37 +4916,37 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_sc_capable(hdev) &&
|
|
|
- !test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ !hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
- if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
|
|
|
lmp_sc_capable(hdev) &&
|
|
|
- !test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev) || !lmp_sc_capable(hdev) ||
|
|
|
- !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
|
|
|
+ !hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
|
|
bool changed;
|
|
|
|
|
|
if (cp->val) {
|
|
|
- changed = !test_and_set_bit(HCI_SC_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev,
|
|
|
+ HCI_SC_ENABLED);
|
|
|
if (cp->val == 0x02)
|
|
|
- set_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_SC_ONLY);
|
|
|
else
|
|
|
- clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SC_ONLY);
|
|
|
} else {
|
|
|
- changed = test_and_clear_bit(HCI_SC_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
- clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_SC_ENABLED);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_SC_ONLY);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
|
|
@@ -4905,15 +4960,15 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev)) {
|
|
|
- err = cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
- MGMT_STATUS_BUSY);
|
|
|
+ err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
|
|
|
+ MGMT_STATUS_BUSY);
|
|
|
goto failed;
|
|
|
}
|
|
|
|
|
|
val = !!cp->val;
|
|
|
|
|
|
- if (val == test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
|
|
|
- (cp->val == 0x02) == test_bit(HCI_SC_ONLY, &hdev->dev_flags)) {
|
|
|
+ if (val == hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
|
|
|
+ (cp->val == 0x02) == hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_SECURE_CONN, hdev);
|
|
|
goto failed;
|
|
|
}
|
|
@@ -4947,27 +5002,26 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEBUG_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (cp->val)
|
|
|
- changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_KEEP_DEBUG_KEYS);
|
|
|
else
|
|
|
- changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_KEEP_DEBUG_KEYS);
|
|
|
|
|
|
if (cp->val == 0x02)
|
|
|
- use_changed = !test_and_set_bit(HCI_USE_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ use_changed = !hci_dev_test_and_set_flag(hdev,
|
|
|
+ HCI_USE_DEBUG_KEYS);
|
|
|
else
|
|
|
- use_changed = test_and_clear_bit(HCI_USE_DEBUG_KEYS,
|
|
|
- &hdev->dev_flags);
|
|
|
+ use_changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_USE_DEBUG_KEYS);
|
|
|
|
|
|
if (hdev_is_powered(hdev) && use_changed &&
|
|
|
- test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
|
|
|
+ hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
|
|
|
u8 mode = (cp->val == 0x02) ? 0x01 : 0x00;
|
|
|
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
|
|
|
sizeof(mode), &mode);
|
|
@@ -4995,32 +5049,32 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
if (cp->privacy != 0x00 && cp->privacy != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
if (hdev_is_powered(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
/* If user space supports this command it is also expected to
|
|
|
* handle IRKs. Therefore, set the HCI_RPA_RESOLVING flag.
|
|
|
*/
|
|
|
- set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_RPA_RESOLVING);
|
|
|
|
|
|
if (cp->privacy) {
|
|
|
- changed = !test_and_set_bit(HCI_PRIVACY, &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_PRIVACY);
|
|
|
memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
|
|
|
- set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
|
|
|
} else {
|
|
|
- changed = test_and_clear_bit(HCI_PRIVACY, &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_PRIVACY);
|
|
|
memset(hdev->irk, 0, sizeof(hdev->irk));
|
|
|
- clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
|
|
|
}
|
|
|
|
|
|
err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev);
|
|
@@ -5063,22 +5117,22 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
irk_count = __le16_to_cpu(cp->irk_count);
|
|
|
if (irk_count > max_irk_count) {
|
|
|
BT_ERR("load_irks: too big irk_count value %u", irk_count);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
|
|
|
if (expected_len != len) {
|
|
|
BT_ERR("load_irks: expected %u bytes, got %u bytes",
|
|
|
expected_len, len);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
BT_DBG("%s irk_count %u", hdev->name, irk_count);
|
|
@@ -5087,9 +5141,9 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
|
|
|
struct mgmt_irk_info *key = &cp->irks[i];
|
|
|
|
|
|
if (!irk_is_valid(key))
|
|
|
- return cmd_status(sk, hdev->id,
|
|
|
- MGMT_OP_LOAD_IRKS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id,
|
|
|
+ MGMT_OP_LOAD_IRKS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
@@ -5109,9 +5163,9 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
|
|
|
BDADDR_ANY);
|
|
|
}
|
|
|
|
|
|
- set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_RPA_RESOLVING);
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0);
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0);
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
@@ -5149,14 +5203,14 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("request for %s", hdev->name);
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
key_count = __le16_to_cpu(cp->key_count);
|
|
|
if (key_count > max_key_count) {
|
|
|
BT_ERR("load_ltks: too big key_count value %u", key_count);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
expected_len = sizeof(*cp) + key_count *
|
|
@@ -5164,8 +5218,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
if (expected_len != len) {
|
|
|
BT_ERR("load_keys: expected %u bytes, got %u bytes",
|
|
|
expected_len, len);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
BT_DBG("%s key_count %u", hdev->name, key_count);
|
|
@@ -5174,9 +5228,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
struct mgmt_ltk_info *key = &cp->keys[i];
|
|
|
|
|
|
if (!ltk_is_valid(key))
|
|
|
- return cmd_status(sk, hdev->id,
|
|
|
- MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id,
|
|
|
+ MGMT_OP_LOAD_LONG_TERM_KEYS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
@@ -5221,7 +5275,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
key->rand);
|
|
|
}
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
|
|
|
NULL, 0);
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
@@ -5229,7 +5283,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int conn_info_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
|
{
|
|
|
struct hci_conn *conn = cmd->user_data;
|
|
|
struct mgmt_rp_get_conn_info rp;
|
|
@@ -5247,8 +5301,8 @@ static int conn_info_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
rp.max_tx_power = HCI_TX_POWER_INVALID;
|
|
|
}
|
|
|
|
|
|
- err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO,
|
|
|
+ status, &rp, sizeof(rp));
|
|
|
|
|
|
hci_conn_drop(conn);
|
|
|
hci_conn_put(conn);
|
|
@@ -5260,7 +5314,7 @@ static void conn_info_refresh_complete(struct hci_dev *hdev, u8 hci_status,
|
|
|
u16 opcode)
|
|
|
{
|
|
|
struct hci_cp_read_rssi *cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
u16 handle;
|
|
|
u8 status;
|
|
@@ -5325,15 +5379,16 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.addr.type = cp->addr.type;
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
- MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
+ MGMT_STATUS_NOT_POWERED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -5344,14 +5399,15 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
|
|
|
|
|
|
if (!conn || conn->state != BT_CONNECTED) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
- MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
+ MGMT_STATUS_NOT_CONNECTED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
if (mgmt_pending_find_data(MGMT_OP_GET_CONN_INFO, hdev, conn)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
- MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
+ MGMT_STATUS_BUSY, &rp, sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -5371,7 +5427,7 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
struct hci_request req;
|
|
|
struct hci_cp_read_tx_power req_txp_cp;
|
|
|
struct hci_cp_read_rssi req_rssi_cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
req_rssi_cp.handle = cpu_to_le16(conn->handle);
|
|
@@ -5419,8 +5475,8 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.tx_power = conn->tx_power;
|
|
|
rp.max_tx_power = conn->max_tx_power;
|
|
|
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
- MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
|
|
|
+ MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
|
|
|
}
|
|
|
|
|
|
unlock:
|
|
@@ -5428,7 +5484,7 @@ unlock:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
+static int clock_info_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
|
|
|
{
|
|
|
struct hci_conn *conn = cmd->user_data;
|
|
|
struct mgmt_rp_get_clock_info rp;
|
|
@@ -5453,8 +5509,8 @@ static int clock_info_cmd_complete(struct pending_cmd *cmd, u8 status)
|
|
|
}
|
|
|
|
|
|
complete:
|
|
|
- err = cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
|
|
|
- sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
|
|
|
+ sizeof(rp));
|
|
|
|
|
|
if (conn) {
|
|
|
hci_conn_drop(conn);
|
|
@@ -5467,7 +5523,7 @@ complete:
|
|
|
static void get_clock_info_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
struct hci_cp_read_clock *hci_cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_conn *conn;
|
|
|
|
|
|
BT_DBG("%s status %u", hdev->name, status);
|
|
@@ -5502,7 +5558,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
struct mgmt_cp_get_clock_info *cp = data;
|
|
|
struct mgmt_rp_get_clock_info rp;
|
|
|
struct hci_cp_read_clock hci_cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
struct hci_conn *conn;
|
|
|
int err;
|
|
@@ -5514,15 +5570,16 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
rp.addr.type = cp->addr.type;
|
|
|
|
|
|
if (cp->addr.type != BDADDR_BREDR)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &rp, sizeof(rp));
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (!hdev_is_powered(hdev)) {
|
|
|
- err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
|
|
|
- MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CLOCK_INFO,
|
|
|
+ MGMT_STATUS_NOT_POWERED, &rp,
|
|
|
+ sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
@@ -5530,10 +5587,10 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
|
|
|
&cp->addr.bdaddr);
|
|
|
if (!conn || conn->state != BT_CONNECTED) {
|
|
|
- err = cmd_complete(sk, hdev->id,
|
|
|
- MGMT_OP_GET_CLOCK_INFO,
|
|
|
- MGMT_STATUS_NOT_CONNECTED,
|
|
|
- &rp, sizeof(rp));
|
|
|
+ err = mgmt_cmd_complete(sk, hdev->id,
|
|
|
+ MGMT_OP_GET_CLOCK_INFO,
|
|
|
+ MGMT_STATUS_NOT_CONNECTED,
|
|
|
+ &rp, sizeof(rp));
|
|
|
goto unlock;
|
|
|
}
|
|
|
} else {
|
|
@@ -5644,7 +5701,7 @@ static void device_added(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
static void add_device_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status 0x%02x", status);
|
|
|
|
|
@@ -5665,7 +5722,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_add_device *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
u8 auto_conn, addr_type;
|
|
|
int err;
|
|
@@ -5674,14 +5731,14 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
if (!bdaddr_type_is_valid(cp->addr.type) ||
|
|
|
!bacmp(&cp->addr.bdaddr, BDADDR_ANY))
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
if (cp->action != 0x00 && cp->action != 0x01 && cp->action != 0x02)
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
|
|
- MGMT_STATUS_INVALID_PARAMS,
|
|
|
- &cp->addr, sizeof(cp->addr));
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS,
|
|
|
+ &cp->addr, sizeof(cp->addr));
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
@@ -5767,7 +5824,7 @@ static void device_removed(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
static void remove_device_complete(struct hci_dev *hdev, u8 status, u16 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("status 0x%02x", status);
|
|
|
|
|
@@ -5788,7 +5845,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,
|
|
|
void *data, u16 len)
|
|
|
{
|
|
|
struct mgmt_cp_remove_device *cp = data;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct hci_request req;
|
|
|
int err;
|
|
|
|
|
@@ -5921,15 +5978,15 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
int i;
|
|
|
|
|
|
if (!lmp_le_capable(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
param_count = __le16_to_cpu(cp->param_count);
|
|
|
if (param_count > max_param_count) {
|
|
|
BT_ERR("load_conn_param: too big param_count value %u",
|
|
|
param_count);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
expected_len = sizeof(*cp) + param_count *
|
|
@@ -5937,8 +5994,8 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
if (expected_len != len) {
|
|
|
BT_ERR("load_conn_param: expected %u bytes, got %u bytes",
|
|
|
expected_len, len);
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
}
|
|
|
|
|
|
BT_DBG("%s param_count %u", hdev->name, param_count);
|
|
@@ -5993,7 +6050,8 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
|
|
|
hci_dev_unlock(hdev);
|
|
|
|
|
|
- return cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0, NULL, 0);
|
|
|
+ return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_LOAD_CONN_PARAM, 0,
|
|
|
+ NULL, 0);
|
|
|
}
|
|
|
|
|
|
static int set_external_config(struct sock *sk, struct hci_dev *hdev,
|
|
@@ -6006,25 +6064,23 @@ static int set_external_config(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (hdev_is_powered(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (cp->config != 0x00 && cp->config != 0x01)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_EXTERNAL_CONFIG,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
|
if (cp->config)
|
|
|
- changed = !test_and_set_bit(HCI_EXT_CONFIGURED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_EXT_CONFIGURED);
|
|
|
else
|
|
|
- changed = test_and_clear_bit(HCI_EXT_CONFIGURED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_EXT_CONFIGURED);
|
|
|
|
|
|
err = send_options_rsp(sk, MGMT_OP_SET_EXTERNAL_CONFIG, hdev);
|
|
|
if (err < 0)
|
|
@@ -6035,12 +6091,12 @@ static int set_external_config(struct sock *sk, struct hci_dev *hdev,
|
|
|
|
|
|
err = new_options(hdev, sk);
|
|
|
|
|
|
- if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) == is_configured(hdev)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) == is_configured(hdev)) {
|
|
|
mgmt_index_removed(hdev);
|
|
|
|
|
|
- if (test_and_change_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
|
|
|
- set_bit(HCI_CONFIG, &hdev->dev_flags);
|
|
|
- set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
|
|
|
+ if (hci_dev_test_and_change_flag(hdev, HCI_UNCONFIGURED)) {
|
|
|
+ hci_dev_set_flag(hdev, HCI_CONFIG);
|
|
|
+ hci_dev_set_flag(hdev, HCI_AUTO_OFF);
|
|
|
|
|
|
queue_work(hdev->req_workqueue, &hdev->power_on);
|
|
|
} else {
|
|
@@ -6064,16 +6120,16 @@ static int set_public_address(struct sock *sk, struct hci_dev *hdev,
|
|
|
BT_DBG("%s", hdev->name);
|
|
|
|
|
|
if (hdev_is_powered(hdev))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
- MGMT_STATUS_REJECTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
+ MGMT_STATUS_REJECTED);
|
|
|
|
|
|
if (!bacmp(&cp->bdaddr, BDADDR_ANY))
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
|
|
|
if (!hdev->set_bdaddr)
|
|
|
- return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
- MGMT_STATUS_NOT_SUPPORTED);
|
|
|
+ return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
|
|
|
+ MGMT_STATUS_NOT_SUPPORTED);
|
|
|
|
|
|
hci_dev_lock(hdev);
|
|
|
|
|
@@ -6087,16 +6143,16 @@ static int set_public_address(struct sock *sk, struct hci_dev *hdev,
|
|
|
if (!changed)
|
|
|
goto unlock;
|
|
|
|
|
|
- if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
|
|
|
err = new_options(hdev, sk);
|
|
|
|
|
|
if (is_configured(hdev)) {
|
|
|
mgmt_index_removed(hdev);
|
|
|
|
|
|
- clear_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_UNCONFIGURED);
|
|
|
|
|
|
- set_bit(HCI_CONFIG, &hdev->dev_flags);
|
|
|
- set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
|
|
|
+ hci_dev_set_flag(hdev, HCI_CONFIG);
|
|
|
+ hci_dev_set_flag(hdev, HCI_AUTO_OFF);
|
|
|
|
|
|
queue_work(hdev->req_workqueue, &hdev->power_on);
|
|
|
}
|
|
@@ -6106,81 +6162,91 @@ unlock:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-static const struct mgmt_handler {
|
|
|
- int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
|
|
|
- u16 data_len);
|
|
|
- bool var_len;
|
|
|
- size_t data_len;
|
|
|
-} mgmt_handlers[] = {
|
|
|
+static const struct hci_mgmt_handler mgmt_handlers[] = {
|
|
|
{ NULL }, /* 0x0000 (no command) */
|
|
|
- { read_version, false, MGMT_READ_VERSION_SIZE },
|
|
|
- { read_commands, false, MGMT_READ_COMMANDS_SIZE },
|
|
|
- { read_index_list, false, MGMT_READ_INDEX_LIST_SIZE },
|
|
|
- { read_controller_info, false, MGMT_READ_INFO_SIZE },
|
|
|
- { set_powered, false, MGMT_SETTING_SIZE },
|
|
|
- { set_discoverable, false, MGMT_SET_DISCOVERABLE_SIZE },
|
|
|
- { set_connectable, false, MGMT_SETTING_SIZE },
|
|
|
- { set_fast_connectable, false, MGMT_SETTING_SIZE },
|
|
|
- { set_bondable, false, MGMT_SETTING_SIZE },
|
|
|
- { set_link_security, false, MGMT_SETTING_SIZE },
|
|
|
- { set_ssp, false, MGMT_SETTING_SIZE },
|
|
|
- { set_hs, false, MGMT_SETTING_SIZE },
|
|
|
- { set_le, false, MGMT_SETTING_SIZE },
|
|
|
- { set_dev_class, false, MGMT_SET_DEV_CLASS_SIZE },
|
|
|
- { set_local_name, false, MGMT_SET_LOCAL_NAME_SIZE },
|
|
|
- { add_uuid, false, MGMT_ADD_UUID_SIZE },
|
|
|
- { remove_uuid, false, MGMT_REMOVE_UUID_SIZE },
|
|
|
- { load_link_keys, true, MGMT_LOAD_LINK_KEYS_SIZE },
|
|
|
- { load_long_term_keys, true, MGMT_LOAD_LONG_TERM_KEYS_SIZE },
|
|
|
- { disconnect, false, MGMT_DISCONNECT_SIZE },
|
|
|
- { get_connections, false, MGMT_GET_CONNECTIONS_SIZE },
|
|
|
- { pin_code_reply, false, MGMT_PIN_CODE_REPLY_SIZE },
|
|
|
- { pin_code_neg_reply, false, MGMT_PIN_CODE_NEG_REPLY_SIZE },
|
|
|
- { set_io_capability, false, MGMT_SET_IO_CAPABILITY_SIZE },
|
|
|
- { pair_device, false, MGMT_PAIR_DEVICE_SIZE },
|
|
|
- { cancel_pair_device, false, MGMT_CANCEL_PAIR_DEVICE_SIZE },
|
|
|
- { unpair_device, false, MGMT_UNPAIR_DEVICE_SIZE },
|
|
|
- { user_confirm_reply, false, MGMT_USER_CONFIRM_REPLY_SIZE },
|
|
|
- { user_confirm_neg_reply, false, MGMT_USER_CONFIRM_NEG_REPLY_SIZE },
|
|
|
- { user_passkey_reply, false, MGMT_USER_PASSKEY_REPLY_SIZE },
|
|
|
- { user_passkey_neg_reply, false, MGMT_USER_PASSKEY_NEG_REPLY_SIZE },
|
|
|
- { read_local_oob_data, false, MGMT_READ_LOCAL_OOB_DATA_SIZE },
|
|
|
- { add_remote_oob_data, true, MGMT_ADD_REMOTE_OOB_DATA_SIZE },
|
|
|
- { remove_remote_oob_data, false, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE },
|
|
|
- { start_discovery, false, MGMT_START_DISCOVERY_SIZE },
|
|
|
- { stop_discovery, false, MGMT_STOP_DISCOVERY_SIZE },
|
|
|
- { confirm_name, false, MGMT_CONFIRM_NAME_SIZE },
|
|
|
- { block_device, false, MGMT_BLOCK_DEVICE_SIZE },
|
|
|
- { unblock_device, false, MGMT_UNBLOCK_DEVICE_SIZE },
|
|
|
- { set_device_id, false, MGMT_SET_DEVICE_ID_SIZE },
|
|
|
- { set_advertising, false, MGMT_SETTING_SIZE },
|
|
|
- { set_bredr, false, MGMT_SETTING_SIZE },
|
|
|
- { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE },
|
|
|
- { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
|
|
|
- { set_secure_conn, false, MGMT_SETTING_SIZE },
|
|
|
- { set_debug_keys, false, MGMT_SETTING_SIZE },
|
|
|
- { set_privacy, false, MGMT_SET_PRIVACY_SIZE },
|
|
|
- { load_irks, true, MGMT_LOAD_IRKS_SIZE },
|
|
|
- { get_conn_info, false, MGMT_GET_CONN_INFO_SIZE },
|
|
|
- { get_clock_info, false, MGMT_GET_CLOCK_INFO_SIZE },
|
|
|
- { add_device, false, MGMT_ADD_DEVICE_SIZE },
|
|
|
- { remove_device, false, MGMT_REMOVE_DEVICE_SIZE },
|
|
|
- { load_conn_param, true, MGMT_LOAD_CONN_PARAM_SIZE },
|
|
|
- { read_unconf_index_list, false, MGMT_READ_UNCONF_INDEX_LIST_SIZE },
|
|
|
- { read_config_info, false, MGMT_READ_CONFIG_INFO_SIZE },
|
|
|
- { set_external_config, false, MGMT_SET_EXTERNAL_CONFIG_SIZE },
|
|
|
- { set_public_address, false, MGMT_SET_PUBLIC_ADDRESS_SIZE },
|
|
|
- { start_service_discovery,true, MGMT_START_SERVICE_DISCOVERY_SIZE },
|
|
|
+ { read_version, MGMT_READ_VERSION_SIZE,
|
|
|
+ HCI_MGMT_NO_HDEV },
|
|
|
+ { read_commands, MGMT_READ_COMMANDS_SIZE,
|
|
|
+ HCI_MGMT_NO_HDEV },
|
|
|
+ { read_index_list, MGMT_READ_INDEX_LIST_SIZE,
|
|
|
+ HCI_MGMT_NO_HDEV },
|
|
|
+ { read_controller_info, MGMT_READ_INFO_SIZE, 0 },
|
|
|
+ { set_powered, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_discoverable, MGMT_SET_DISCOVERABLE_SIZE, 0 },
|
|
|
+ { set_connectable, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_fast_connectable, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_bondable, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_link_security, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_ssp, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_hs, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_le, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_dev_class, MGMT_SET_DEV_CLASS_SIZE, 0 },
|
|
|
+ { set_local_name, MGMT_SET_LOCAL_NAME_SIZE, 0 },
|
|
|
+ { add_uuid, MGMT_ADD_UUID_SIZE, 0 },
|
|
|
+ { remove_uuid, MGMT_REMOVE_UUID_SIZE, 0 },
|
|
|
+ { load_link_keys, MGMT_LOAD_LINK_KEYS_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
+ { load_long_term_keys, MGMT_LOAD_LONG_TERM_KEYS_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
+ { disconnect, MGMT_DISCONNECT_SIZE, 0 },
|
|
|
+ { get_connections, MGMT_GET_CONNECTIONS_SIZE, 0 },
|
|
|
+ { pin_code_reply, MGMT_PIN_CODE_REPLY_SIZE, 0 },
|
|
|
+ { pin_code_neg_reply, MGMT_PIN_CODE_NEG_REPLY_SIZE, 0 },
|
|
|
+ { set_io_capability, MGMT_SET_IO_CAPABILITY_SIZE, 0 },
|
|
|
+ { pair_device, MGMT_PAIR_DEVICE_SIZE, 0 },
|
|
|
+ { cancel_pair_device, MGMT_CANCEL_PAIR_DEVICE_SIZE, 0 },
|
|
|
+ { unpair_device, MGMT_UNPAIR_DEVICE_SIZE, 0 },
|
|
|
+ { user_confirm_reply, MGMT_USER_CONFIRM_REPLY_SIZE, 0 },
|
|
|
+ { user_confirm_neg_reply, MGMT_USER_CONFIRM_NEG_REPLY_SIZE, 0 },
|
|
|
+ { user_passkey_reply, MGMT_USER_PASSKEY_REPLY_SIZE, 0 },
|
|
|
+ { user_passkey_neg_reply, MGMT_USER_PASSKEY_NEG_REPLY_SIZE, 0 },
|
|
|
+ { read_local_oob_data, MGMT_READ_LOCAL_OOB_DATA_SIZE },
|
|
|
+ { add_remote_oob_data, MGMT_ADD_REMOTE_OOB_DATA_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
+ { remove_remote_oob_data, MGMT_REMOVE_REMOTE_OOB_DATA_SIZE, 0 },
|
|
|
+ { start_discovery, MGMT_START_DISCOVERY_SIZE, 0 },
|
|
|
+ { stop_discovery, MGMT_STOP_DISCOVERY_SIZE, 0 },
|
|
|
+ { confirm_name, MGMT_CONFIRM_NAME_SIZE, 0 },
|
|
|
+ { block_device, MGMT_BLOCK_DEVICE_SIZE, 0 },
|
|
|
+ { unblock_device, MGMT_UNBLOCK_DEVICE_SIZE, 0 },
|
|
|
+ { set_device_id, MGMT_SET_DEVICE_ID_SIZE, 0 },
|
|
|
+ { set_advertising, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_bredr, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_static_address, MGMT_SET_STATIC_ADDRESS_SIZE, 0 },
|
|
|
+ { set_scan_params, MGMT_SET_SCAN_PARAMS_SIZE, 0 },
|
|
|
+ { set_secure_conn, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_debug_keys, MGMT_SETTING_SIZE, 0 },
|
|
|
+ { set_privacy, MGMT_SET_PRIVACY_SIZE, 0 },
|
|
|
+ { load_irks, MGMT_LOAD_IRKS_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
+ { get_conn_info, MGMT_GET_CONN_INFO_SIZE, 0 },
|
|
|
+ { get_clock_info, MGMT_GET_CLOCK_INFO_SIZE, 0 },
|
|
|
+ { add_device, MGMT_ADD_DEVICE_SIZE, 0 },
|
|
|
+ { remove_device, MGMT_REMOVE_DEVICE_SIZE, 0 },
|
|
|
+ { load_conn_param, MGMT_LOAD_CONN_PARAM_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
+ { read_unconf_index_list, MGMT_READ_UNCONF_INDEX_LIST_SIZE,
|
|
|
+ HCI_MGMT_NO_HDEV },
|
|
|
+ { read_config_info, MGMT_READ_CONFIG_INFO_SIZE,
|
|
|
+ HCI_MGMT_UNCONFIGURED },
|
|
|
+ { set_external_config, MGMT_SET_EXTERNAL_CONFIG_SIZE,
|
|
|
+ HCI_MGMT_UNCONFIGURED },
|
|
|
+ { set_public_address, MGMT_SET_PUBLIC_ADDRESS_SIZE,
|
|
|
+ HCI_MGMT_UNCONFIGURED },
|
|
|
+ { start_service_discovery, MGMT_START_SERVICE_DISCOVERY_SIZE,
|
|
|
+ HCI_MGMT_VAR_LEN },
|
|
|
};
|
|
|
|
|
|
-int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
|
|
|
+int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk,
|
|
|
+ struct msghdr *msg, size_t msglen)
|
|
|
{
|
|
|
void *buf;
|
|
|
u8 *cp;
|
|
|
struct mgmt_hdr *hdr;
|
|
|
u16 opcode, index, len;
|
|
|
struct hci_dev *hdev = NULL;
|
|
|
- const struct mgmt_handler *handler;
|
|
|
+ const struct hci_mgmt_handler *handler;
|
|
|
+ bool var_len, no_hdev;
|
|
|
int err;
|
|
|
|
|
|
BT_DBG("got %zu bytes", msglen);
|
|
@@ -6207,60 +6273,52 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ if (opcode >= chan->handler_count ||
|
|
|
+ chan->handlers[opcode].func == NULL) {
|
|
|
+ BT_DBG("Unknown op %u", opcode);
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_UNKNOWN_COMMAND);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ handler = &chan->handlers[opcode];
|
|
|
+
|
|
|
if (index != MGMT_INDEX_NONE) {
|
|
|
hdev = hci_dev_get(index);
|
|
|
if (!hdev) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_INDEX);
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_INVALID_INDEX);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
|
|
|
- test_bit(HCI_CONFIG, &hdev->dev_flags) ||
|
|
|
- test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_INDEX);
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SETUP) ||
|
|
|
+ hci_dev_test_flag(hdev, HCI_CONFIG) ||
|
|
|
+ hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_INVALID_INDEX);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
|
|
|
- opcode != MGMT_OP_READ_CONFIG_INFO &&
|
|
|
- opcode != MGMT_OP_SET_EXTERNAL_CONFIG &&
|
|
|
- opcode != MGMT_OP_SET_PUBLIC_ADDRESS) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_INDEX);
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
|
|
|
+ !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_INVALID_INDEX);
|
|
|
goto done;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (opcode >= ARRAY_SIZE(mgmt_handlers) ||
|
|
|
- mgmt_handlers[opcode].func == NULL) {
|
|
|
- BT_DBG("Unknown op %u", opcode);
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_UNKNOWN_COMMAND);
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- if (hdev && (opcode <= MGMT_OP_READ_INDEX_LIST ||
|
|
|
- opcode == MGMT_OP_READ_UNCONF_INDEX_LIST)) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_INDEX);
|
|
|
+ no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
|
|
|
+ if (no_hdev != !hdev) {
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_INVALID_INDEX);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
- if (!hdev && (opcode > MGMT_OP_READ_INDEX_LIST &&
|
|
|
- opcode != MGMT_OP_READ_UNCONF_INDEX_LIST)) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_INDEX);
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- handler = &mgmt_handlers[opcode];
|
|
|
-
|
|
|
- if ((handler->var_len && len < handler->data_len) ||
|
|
|
- (!handler->var_len && len != handler->data_len)) {
|
|
|
- err = cmd_status(sk, index, opcode,
|
|
|
- MGMT_STATUS_INVALID_PARAMS);
|
|
|
+ var_len = (handler->flags & HCI_MGMT_VAR_LEN);
|
|
|
+ if ((var_len && len < handler->data_len) ||
|
|
|
+ (!var_len && len != handler->data_len)) {
|
|
|
+ err = mgmt_cmd_status(sk, index, opcode,
|
|
|
+ MGMT_STATUS_INVALID_PARAMS);
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
@@ -6291,7 +6349,7 @@ void mgmt_index_added(struct hci_dev *hdev)
|
|
|
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
|
|
|
return;
|
|
|
|
|
|
- if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
|
|
|
mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL);
|
|
|
else
|
|
|
mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
|
|
@@ -6309,7 +6367,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
|
|
|
|
|
|
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
|
|
|
|
|
|
- if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
|
|
|
mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL);
|
|
|
else
|
|
|
mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
|
|
@@ -6377,7 +6435,7 @@ static int powered_update_hci(struct hci_dev *hdev)
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
- if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
|
|
|
!lmp_host_ssp_capable(hdev)) {
|
|
|
u8 mode = 0x01;
|
|
|
|
|
@@ -6391,7 +6449,7 @@ static int powered_update_hci(struct hci_dev *hdev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ENABLED) &&
|
|
|
lmp_bredr_capable(hdev)) {
|
|
|
struct hci_cp_write_le_host_supported cp;
|
|
|
|
|
@@ -6412,24 +6470,27 @@ static int powered_update_hci(struct hci_dev *hdev)
|
|
|
* advertising data. This also applies to the case
|
|
|
* where BR/EDR was toggled during the AUTO_OFF phase.
|
|
|
*/
|
|
|
- if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
|
|
|
update_adv_data(&req);
|
|
|
update_scan_rsp_data(&req);
|
|
|
}
|
|
|
|
|
|
- if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
|
|
enable_advertising(&req);
|
|
|
|
|
|
restart_le_actions(&req);
|
|
|
}
|
|
|
|
|
|
- link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
|
|
|
+ link_sec = hci_dev_test_flag(hdev, HCI_LINK_SECURITY);
|
|
|
if (link_sec != test_bit(HCI_AUTH, &hdev->flags))
|
|
|
hci_req_add(&req, HCI_OP_WRITE_AUTH_ENABLE,
|
|
|
sizeof(link_sec), &link_sec);
|
|
|
|
|
|
if (lmp_bredr_capable(hdev)) {
|
|
|
- write_fast_connectable(&req, false);
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_FAST_CONNECTABLE))
|
|
|
+ write_fast_connectable(&req, true);
|
|
|
+ else
|
|
|
+ write_fast_connectable(&req, false);
|
|
|
__hci_update_page_scan(&req);
|
|
|
update_class(&req);
|
|
|
update_name(&req);
|
|
@@ -6445,7 +6506,7 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
|
|
|
u8 status, zero_cod[] = { 0, 0, 0 };
|
|
|
int err;
|
|
|
|
|
|
- if (!test_bit(HCI_MGMT, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_MGMT))
|
|
|
return 0;
|
|
|
|
|
|
if (powered) {
|
|
@@ -6466,7 +6527,7 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
|
|
|
* been triggered, potentially causing misleading DISCONNECTED
|
|
|
* status responses.
|
|
|
*/
|
|
|
- if (test_bit(HCI_UNREGISTER, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
|
|
status = MGMT_STATUS_INVALID_INDEX;
|
|
|
else
|
|
|
status = MGMT_STATUS_NOT_POWERED;
|
|
@@ -6488,7 +6549,7 @@ new_settings:
|
|
|
|
|
|
void mgmt_set_powered_failed(struct hci_dev *hdev, int err)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
u8 status;
|
|
|
|
|
|
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
|
|
@@ -6500,7 +6561,7 @@ void mgmt_set_powered_failed(struct hci_dev *hdev, int err)
|
|
|
else
|
|
|
status = MGMT_STATUS_FAILED;
|
|
|
|
|
|
- cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
|
|
|
+ mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
|
|
|
|
|
|
mgmt_pending_remove(cmd);
|
|
|
}
|
|
@@ -6516,11 +6577,11 @@ void mgmt_discoverable_timeout(struct hci_dev *hdev)
|
|
|
* of a timeout triggered from general discoverable, it is
|
|
|
* safe to unconditionally clear the flag.
|
|
|
*/
|
|
|
- clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
|
|
|
- clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
- if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
|
|
|
u8 scan = SCAN_PAGE;
|
|
|
hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE,
|
|
|
sizeof(scan), &scan);
|
|
@@ -6739,7 +6800,7 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
|
|
|
sizeof(*ev) + eir_len, NULL);
|
|
|
}
|
|
|
|
|
|
-static void disconnect_rsp(struct pending_cmd *cmd, void *data)
|
|
|
+static void disconnect_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
struct sock **sk = data;
|
|
|
|
|
@@ -6751,7 +6812,7 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
|
|
|
mgmt_pending_remove(cmd);
|
|
|
}
|
|
|
|
|
|
-static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
|
|
|
+static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
struct hci_dev *hdev = data;
|
|
|
struct mgmt_cp_unpair_device *cp = cmd->param;
|
|
@@ -6764,7 +6825,7 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
|
|
|
|
|
|
bool mgmt_powering_down(struct hci_dev *hdev)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
struct mgmt_mode *cp;
|
|
|
|
|
|
cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
|
|
@@ -6819,7 +6880,7 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
{
|
|
|
u8 bdaddr_type = link_to_bdaddr(link_type, addr_type);
|
|
|
struct mgmt_cp_disconnect *cp;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
|
|
|
hdev);
|
|
@@ -6874,7 +6935,7 @@ void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
|
|
|
void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
|
|
|
if (!cmd)
|
|
@@ -6887,7 +6948,7 @@ void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
|
|
|
if (!cmd)
|
|
@@ -6932,7 +6993,7 @@ static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
u8 link_type, u8 addr_type, u8 status,
|
|
|
u8 opcode)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
cmd = mgmt_pending_find(opcode, hdev);
|
|
|
if (!cmd)
|
|
@@ -6993,7 +7054,7 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|
|
void mgmt_auth_failed(struct hci_conn *conn, u8 hci_status)
|
|
|
{
|
|
|
struct mgmt_ev_auth_failed ev;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
u8 status = mgmt_status(hci_status);
|
|
|
|
|
|
bacpy(&ev.addr.bdaddr, &conn->dst);
|
|
@@ -7024,11 +7085,9 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
|
|
|
}
|
|
|
|
|
|
if (test_bit(HCI_AUTH, &hdev->flags))
|
|
|
- changed = !test_and_set_bit(HCI_LINK_SECURITY,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_LINK_SECURITY);
|
|
|
else
|
|
|
- changed = test_and_clear_bit(HCI_LINK_SECURITY,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
|
|
|
|
|
|
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
|
|
|
&match);
|
|
@@ -7064,9 +7123,9 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
|
|
|
if (status) {
|
|
|
u8 mgmt_err = mgmt_status(status);
|
|
|
|
|
|
- if (enable && test_and_clear_bit(HCI_SSP_ENABLED,
|
|
|
- &hdev->dev_flags)) {
|
|
|
- clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ if (enable && hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_SSP_ENABLED)) {
|
|
|
+ hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
|
|
|
new_settings(hdev, NULL);
|
|
|
}
|
|
|
|
|
@@ -7076,14 +7135,14 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
|
|
|
}
|
|
|
|
|
|
if (enable) {
|
|
|
- changed = !test_and_set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
|
|
|
+ changed = !hci_dev_test_and_set_flag(hdev, HCI_SSP_ENABLED);
|
|
|
} else {
|
|
|
- changed = test_and_clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
|
|
|
if (!changed)
|
|
|
- changed = test_and_clear_bit(HCI_HS_ENABLED,
|
|
|
- &hdev->dev_flags);
|
|
|
+ changed = hci_dev_test_and_clear_flag(hdev,
|
|
|
+ HCI_HS_ENABLED);
|
|
|
else
|
|
|
- clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
|
|
|
+ hci_dev_clear_flag(hdev, HCI_HS_ENABLED);
|
|
|
}
|
|
|
|
|
|
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
|
|
@@ -7096,8 +7155,8 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
|
|
|
- if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
|
|
|
- if (test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
|
|
|
+ if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
|
|
|
hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
|
|
|
sizeof(enable), &enable);
|
|
|
update_eir(&req);
|
|
@@ -7108,7 +7167,7 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
|
|
|
hci_req_run(&req, NULL);
|
|
|
}
|
|
|
|
|
|
-static void sk_lookup(struct pending_cmd *cmd, void *data)
|
|
|
+static void sk_lookup(struct mgmt_pending_cmd *cmd, void *data)
|
|
|
{
|
|
|
struct cmd_lookup *match = data;
|
|
|
|
|
@@ -7138,7 +7197,7 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
|
|
|
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
|
|
|
{
|
|
|
struct mgmt_cp_set_local_name ev;
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
if (status)
|
|
|
return;
|
|
@@ -7166,7 +7225,7 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
|
|
|
u8 *rand192, u8 *hash256, u8 *rand256,
|
|
|
u8 status)
|
|
|
{
|
|
|
- struct pending_cmd *cmd;
|
|
|
+ struct mgmt_pending_cmd *cmd;
|
|
|
|
|
|
BT_DBG("%s status %u", hdev->name, status);
|
|
|
|
|
@@ -7175,8 +7234,8 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
|
|
|
return;
|
|
|
|
|
|
if (status) {
|
|
|
- cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
- mgmt_status(status));
|
|
|
+ mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
|
|
|
+ mgmt_status(status));
|
|
|
} else {
|
|
|
struct mgmt_rp_read_local_oob_data rp;
|
|
|
size_t rp_size = sizeof(rp);
|
|
@@ -7191,8 +7250,9 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
|
|
|
rp_size -= sizeof(rp.hash256) + sizeof(rp.rand256);
|
|
|
}
|
|
|
|
|
|
- cmd_complete(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, 0,
|
|
|
- &rp, rp_size);
|
|
|
+ mgmt_cmd_complete(cmd->sk, hdev->id,
|
|
|
+ MGMT_OP_READ_LOCAL_OOB_DATA, 0,
|
|
|
+ &rp, rp_size);
|
|
|
}
|
|
|
|
|
|
mgmt_pending_remove(cmd);
|
|
@@ -7268,7 +7328,7 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
|
|
|
static void restart_le_scan(struct hci_dev *hdev)
|
|
|
{
|
|
|
/* If controller is not scanning we are done. */
|
|
|
- if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
|
|
return;
|
|
|
|
|
|
if (time_after(jiffies + DISCOV_LE_RESTART_DELAY,
|
|
@@ -7280,14 +7340,58 @@ static void restart_le_scan(struct hci_dev *hdev)
|
|
|
DISCOV_LE_RESTART_DELAY);
|
|
|
}
|
|
|
|
|
|
+static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
|
|
|
+ u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
|
|
|
+{
|
|
|
+ /* If a RSSI threshold has been specified, and
|
|
|
+ * HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set, then all results with
|
|
|
+ * a RSSI smaller than the RSSI threshold will be dropped. If the quirk
|
|
|
+ * is set, let it through for further processing, as we might need to
|
|
|
+ * restart the scan.
|
|
|
+ *
|
|
|
+ * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry,
|
|
|
+ * the results are also dropped.
|
|
|
+ */
|
|
|
+ if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
|
|
|
+ (rssi == HCI_RSSI_INVALID ||
|
|
|
+ (rssi < hdev->discovery.rssi &&
|
|
|
+ !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (hdev->discovery.uuid_count != 0) {
|
|
|
+ /* If a list of UUIDs is provided in filter, results with no
|
|
|
+ * matching UUID should be dropped.
|
|
|
+ */
|
|
|
+ if (!eir_has_uuids(eir, eir_len, hdev->discovery.uuid_count,
|
|
|
+ hdev->discovery.uuids) &&
|
|
|
+ !eir_has_uuids(scan_rsp, scan_rsp_len,
|
|
|
+ hdev->discovery.uuid_count,
|
|
|
+ hdev->discovery.uuids))
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If duplicate filtering does not report RSSI changes, then restart
|
|
|
+ * scanning to ensure updated result with updated RSSI values.
|
|
|
+ */
|
|
|
+ if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)) {
|
|
|
+ restart_le_scan(hdev);
|
|
|
+
|
|
|
+ /* Validate RSSI value against the RSSI threshold once more. */
|
|
|
+ if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
|
|
|
+ rssi < hdev->discovery.rssi)
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
|
|
u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
|
|
|
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
|
|
|
{
|
|
|
char buf[512];
|
|
|
- struct mgmt_ev_device_found *ev = (void *) buf;
|
|
|
+ struct mgmt_ev_device_found *ev = (void *)buf;
|
|
|
size_t ev_size;
|
|
|
- bool match;
|
|
|
|
|
|
/* Don't send events for a non-kernel initiated discovery. With
|
|
|
* LE one exception is if we have pend_le_reports > 0 in which
|
|
@@ -7300,21 +7404,12 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* When using service discovery with a RSSI threshold, then check
|
|
|
- * if such a RSSI threshold is specified. If a RSSI threshold has
|
|
|
- * been specified, and HCI_QUIRK_STRICT_DUPLICATE_FILTER is not set,
|
|
|
- * then all results with a RSSI smaller than the RSSI threshold will be
|
|
|
- * dropped. If the quirk is set, let it through for further processing,
|
|
|
- * as we might need to restart the scan.
|
|
|
- *
|
|
|
- * For BR/EDR devices (pre 1.2) providing no RSSI during inquiry,
|
|
|
- * the results are also dropped.
|
|
|
- */
|
|
|
- if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
|
|
|
- (rssi == HCI_RSSI_INVALID ||
|
|
|
- (rssi < hdev->discovery.rssi &&
|
|
|
- !test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
|
|
|
- return;
|
|
|
+ if (hdev->discovery.result_filtering) {
|
|
|
+ /* We are using service discovery */
|
|
|
+ if (!is_filter_match(hdev, rssi, eir, eir_len, scan_rsp,
|
|
|
+ scan_rsp_len))
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
/* Make sure that the buffer is big enough. The 5 extra bytes
|
|
|
* are for the potential CoD field.
|
|
@@ -7341,87 +7436,17 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
|
|
|
ev->rssi = rssi;
|
|
|
ev->flags = cpu_to_le32(flags);
|
|
|
|
|
|
- if (eir_len > 0) {
|
|
|
- /* When using service discovery and a list of UUID is
|
|
|
- * provided, results with no matching UUID should be
|
|
|
- * dropped. In case there is a match the result is
|
|
|
- * kept and checking possible scan response data
|
|
|
- * will be skipped.
|
|
|
- */
|
|
|
- if (hdev->discovery.uuid_count > 0) {
|
|
|
- match = eir_has_uuids(eir, eir_len,
|
|
|
- hdev->discovery.uuid_count,
|
|
|
- hdev->discovery.uuids);
|
|
|
- /* If duplicate filtering does not report RSSI changes,
|
|
|
- * then restart scanning to ensure updated result with
|
|
|
- * updated RSSI values.
|
|
|
- */
|
|
|
- if (match && test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
|
|
|
- &hdev->quirks))
|
|
|
- restart_le_scan(hdev);
|
|
|
- } else {
|
|
|
- match = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (!match && !scan_rsp_len)
|
|
|
- return;
|
|
|
-
|
|
|
+ if (eir_len > 0)
|
|
|
/* Copy EIR or advertising data into event */
|
|
|
memcpy(ev->eir, eir, eir_len);
|
|
|
- } else {
|
|
|
- /* When using service discovery and a list of UUID is
|
|
|
- * provided, results with empty EIR or advertising data
|
|
|
- * should be dropped since they do not match any UUID.
|
|
|
- */
|
|
|
- if (hdev->discovery.uuid_count > 0 && !scan_rsp_len)
|
|
|
- return;
|
|
|
-
|
|
|
- match = false;
|
|
|
- }
|
|
|
|
|
|
if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
|
|
|
eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
|
|
|
dev_class, 3);
|
|
|
|
|
|
- if (scan_rsp_len > 0) {
|
|
|
- /* When using service discovery and a list of UUID is
|
|
|
- * provided, results with no matching UUID should be
|
|
|
- * dropped if there is no previous match from the
|
|
|
- * advertising data.
|
|
|
- */
|
|
|
- if (hdev->discovery.uuid_count > 0) {
|
|
|
- if (!match && !eir_has_uuids(scan_rsp, scan_rsp_len,
|
|
|
- hdev->discovery.uuid_count,
|
|
|
- hdev->discovery.uuids))
|
|
|
- return;
|
|
|
-
|
|
|
- /* If duplicate filtering does not report RSSI changes,
|
|
|
- * then restart scanning to ensure updated result with
|
|
|
- * updated RSSI values.
|
|
|
- */
|
|
|
- if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
|
|
|
- &hdev->quirks))
|
|
|
- restart_le_scan(hdev);
|
|
|
- }
|
|
|
-
|
|
|
+ if (scan_rsp_len > 0)
|
|
|
/* Append scan response data to event */
|
|
|
memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
|
|
|
- } else {
|
|
|
- /* When using service discovery and a list of UUID is
|
|
|
- * provided, results with empty scan response and no
|
|
|
- * previous matched advertising data should be dropped.
|
|
|
- */
|
|
|
- if (hdev->discovery.uuid_count > 0 && !match)
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* Validate the reported RSSI value against the RSSI threshold once more
|
|
|
- * incase HCI_QUIRK_STRICT_DUPLICATE_FILTER forced a restart of LE
|
|
|
- * scanning.
|
|
|
- */
|
|
|
- if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
|
|
|
- rssi < hdev->discovery.rssi)
|
|
|
- return;
|
|
|
|
|
|
ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
|
|
|
ev_size = sizeof(*ev) + eir_len + scan_rsp_len;
|
|
@@ -7474,10 +7499,26 @@ void mgmt_reenable_advertising(struct hci_dev *hdev)
|
|
|
{
|
|
|
struct hci_request req;
|
|
|
|
|
|
- if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
|
|
+ if (!hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
|
|
return;
|
|
|
|
|
|
hci_req_init(&req, hdev);
|
|
|
enable_advertising(&req);
|
|
|
hci_req_run(&req, adv_enable_complete);
|
|
|
}
|
|
|
+
|
|
|
+static struct hci_mgmt_chan chan = {
|
|
|
+ .channel = HCI_CHANNEL_CONTROL,
|
|
|
+ .handler_count = ARRAY_SIZE(mgmt_handlers),
|
|
|
+ .handlers = mgmt_handlers,
|
|
|
+};
|
|
|
+
|
|
|
+int mgmt_init(void)
|
|
|
+{
|
|
|
+ return hci_mgmt_chan_register(&chan);
|
|
|
+}
|
|
|
+
|
|
|
+void mgmt_exit(void)
|
|
|
+{
|
|
|
+ hci_mgmt_chan_unregister(&chan);
|
|
|
+}
|