提交 45e826fd 编写于 作者: D David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2015-02-03

Here's what's likely the last bluetooth-next pull request for 3.20.
Notable changes include:

 - xHCI workaround + a new id for the ath3k driver
 - Several new ids for the btusb driver
 - Support for new Intel Bluetooth controllers
 - Minor cleanups to ieee802154 code
 - Nested sleep warning fix in socket accept() code path
 - Fixes for Out of Band pairing handling
 - Support for LE scan restarting for HCI_QUIRK_STRICT_DUPLICATE_FILTER
 - Improvements to data we expose through debugfs
 - Proper handling of Hardware Error HCI events

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -108,6 +108,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3423) },
{ USB_DEVICE(0x13d3, 0x3432) },
/* Atheros AR5BBU12 with sflash firmware */
......@@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */
......@@ -174,6 +176,8 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
#define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096
#define FW_HDR_SIZE 20
#define TIMEGAP_USEC_MIN 50
#define TIMEGAP_USEC_MAX 100
static int ath3k_load_firmware(struct usb_device *udev,
const struct firmware *firmware)
......@@ -205,6 +209,9 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndbulkpipe(udev, 0x02);
while (count) {
/* workaround the compatibility issue with xHCI controller*/
usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
size = min_t(uint, count, BULK_SIZE);
memcpy(send_buf, firmware->data + sent, size);
......@@ -302,6 +309,9 @@ static int ath3k_load_fwfile(struct usb_device *udev,
pipe = usb_sndbulkpipe(udev, 0x02);
while (count) {
/* workaround the compatibility issue with xHCI controller*/
usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
size = min_t(uint, count, BULK_SIZE);
memcpy(send_buf, firmware->data + sent, size);
......
此差异已折叠。
......@@ -44,9 +44,9 @@
#define CC2520_FREG_MASK 0x3F
/* status byte values */
#define CC2520_STATUS_XOSC32M_STABLE (1 << 7)
#define CC2520_STATUS_RSSI_VALID (1 << 6)
#define CC2520_STATUS_TX_UNDERFLOW (1 << 3)
#define CC2520_STATUS_XOSC32M_STABLE BIT(7)
#define CC2520_STATUS_RSSI_VALID BIT(6)
#define CC2520_STATUS_TX_UNDERFLOW BIT(3)
/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
#define CC2520_MINCHANNEL 11
......@@ -549,14 +549,14 @@ cc2520_ed(struct ieee802154_hw *hw, u8 *level)
u8 rssi;
int ret;
ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
ret = cc2520_read_register(priv, CC2520_RSSISTAT, &status);
if (ret)
return ret;
if (status != RSSI_VALID)
return -EINVAL;
ret = cc2520_read_register(priv , CC2520_RSSI, &rssi);
ret = cc2520_read_register(priv, CC2520_RSSI, &rssi);
if (ret)
return ret;
......
......@@ -79,6 +79,8 @@ struct discovery_state {
s8 rssi;
u16 uuid_count;
u8 (*uuids)[16];
unsigned long scan_start;
unsigned long scan_duration;
};
struct hci_conn_hash {
......@@ -145,6 +147,7 @@ struct oob_data {
struct list_head list;
bdaddr_t bdaddr;
u8 bdaddr_type;
u8 present;
u8 hash192[16];
u8 rand192[16];
u8 hash256[16];
......@@ -232,6 +235,7 @@ struct hci_dev {
__u16 conn_info_min_age;
__u16 conn_info_max_age;
__u8 ssp_debug_mode;
__u8 hw_error_code;
__u32 clock;
__u16 devid_source;
......@@ -293,6 +297,7 @@ struct hci_dev {
struct work_struct power_on;
struct delayed_work power_off;
struct work_struct error_reset;
__u16 discov_timeout;
struct delayed_work discov_off;
......@@ -351,6 +356,7 @@ struct hci_dev {
unsigned long dev_flags;
struct delayed_work le_scan_disable;
struct delayed_work le_scan_restart;
__s8 adv_tx_power;
__u8 adv_data[HCI_MAX_AD_LENGTH];
......@@ -369,6 +375,7 @@ struct hci_dev {
int (*setup)(struct hci_dev *hdev);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
void (*hw_error)(struct hci_dev *hdev, u8 code);
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
};
......@@ -527,6 +534,8 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
hdev->discovery.uuid_count = 0;
kfree(hdev->discovery.uuids);
hdev->discovery.uuids = NULL;
hdev->discovery.scan_start = 0;
hdev->discovery.scan_duration = 0;
}
bool hci_discovery_active(struct hci_dev *hdev);
......@@ -1325,6 +1334,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */
#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
#define DISCOV_BREDR_INQUIRY_LEN 0x08
#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_new_settings(struct hci_dev *hdev);
......@@ -1369,7 +1379,6 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
void mgmt_auth_failed(struct hci_conn *conn, u8 status);
void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status);
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
......
......@@ -301,10 +301,6 @@ struct mgmt_cp_user_passkey_neg_reply {
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020
#define MGMT_READ_LOCAL_OOB_DATA_SIZE 0
struct mgmt_rp_read_local_oob_data {
__u8 hash[16];
__u8 rand[16];
} __packed;
struct mgmt_rp_read_local_oob_ext_data {
__u8 hash192[16];
__u8 rand192[16];
__u8 hash256[16];
......
......@@ -511,13 +511,12 @@ static int bnep_session(void *arg)
static struct device *bnep_get_device(struct bnep_session *session)
{
struct hci_conn *conn;
struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
conn = l2cap_pi(session->sock->sk)->chan->conn->hcon;
if (!conn)
if (!conn || !conn->hcon)
return NULL;
return &conn->dev;
return &conn->hcon->dev;
}
static struct device_type bnep_type = {
......
......@@ -609,6 +609,7 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
u8 mode = 0x01;
hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
sizeof(mode), &mode);
} else {
......@@ -870,8 +871,10 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
/* Enable Secure Connections if supported and configured */
if (bredr_sc_enabled(hdev)) {
if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
bredr_sc_enabled(hdev)) {
u8 support = 0x01;
hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
sizeof(support), &support);
}
......@@ -1614,6 +1617,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
cancel_delayed_work(&hdev->service_cache);
cancel_delayed_work_sync(&hdev->le_scan_disable);
cancel_delayed_work_sync(&hdev->le_scan_restart);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
cancel_delayed_work_sync(&hdev->rpa_expired);
......@@ -1625,6 +1629,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock(hdev);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
if (hdev->dev_type == HCI_BREDR)
mgmt_powered(hdev, 0);
......@@ -1635,6 +1641,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_conn_hash_flush(hdev);
hci_dev_unlock(hdev);
smp_unregister(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
if (hdev->flush)
......@@ -1714,32 +1722,14 @@ int hci_dev_close(__u16 dev)
return err;
}
int hci_dev_reset(__u16 dev)
static int hci_dev_do_reset(struct hci_dev *hdev)
{
struct hci_dev *hdev;
int ret = 0;
int ret;
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
BT_DBG("%s %p", hdev->name, hdev);
hci_req_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
ret = -ENETDOWN;
goto done;
}
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
ret = -EBUSY;
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
ret = -EOPNOTSUPP;
goto done;
}
/* Drop queues */
skb_queue_purge(&hdev->rx_q);
skb_queue_purge(&hdev->cmd_q);
......@@ -1762,12 +1752,41 @@ int hci_dev_reset(__u16 dev)
ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done:
hci_req_unlock(hdev);
hci_dev_put(hdev);
return ret;
}
int hci_dev_reset(__u16 dev)
{
struct hci_dev *hdev;
int err;
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
if (!test_bit(HCI_UP, &hdev->flags)) {
err = -ENETDOWN;
goto done;
}
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
err = -EBUSY;
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
}
err = hci_dev_do_reset(hdev);
done:
hci_dev_put(hdev);
return err;
}
int hci_dev_reset_stat(__u16 dev)
{
struct hci_dev *hdev;
......@@ -2131,8 +2150,24 @@ static void hci_power_off(struct work_struct *work)
BT_DBG("%s", hdev->name);
hci_dev_do_close(hdev);
}
smp_unregister(hdev);
static void hci_error_reset(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
BT_DBG("%s", hdev->name);
if (hdev->hw_error)
hdev->hw_error(hdev, hdev->hw_error_code);
else
BT_ERR("%s hardware error 0x%2.2x", hdev->name,
hdev->hw_error_code);
if (hci_dev_do_close(hdev))
return;
hci_dev_do_open(hdev);
}
static void hci_discov_off(struct work_struct *work)
......@@ -2547,9 +2582,15 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
if (hash192 && rand192) {
memcpy(data->hash192, hash192, sizeof(data->hash192));
memcpy(data->rand192, rand192, sizeof(data->rand192));
if (hash256 && rand256)
data->present = 0x03;
} else {
memset(data->hash192, 0, sizeof(data->hash192));
memset(data->rand192, 0, sizeof(data->rand192));
if (hash256 && rand256)
data->present = 0x02;
else
data->present = 0x00;
}
if (hash256 && rand256) {
......@@ -2558,6 +2599,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
} else {
memset(data->hash256, 0, sizeof(data->hash256));
memset(data->rand256, 0, sizeof(data->rand256));
if (hash192 && rand192)
data->present = 0x01;
}
BT_DBG("%s for %pMR", hdev->name, bdaddr);
......@@ -2788,6 +2831,8 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
return;
}
hdev->discovery.scan_start = 0;
switch (hdev->discovery.type) {
case DISCOV_TYPE_LE:
hci_dev_lock(hdev);
......@@ -2827,6 +2872,8 @@ static void le_scan_disable_work(struct work_struct *work)
BT_DBG("%s", hdev->name);
cancel_delayed_work_sync(&hdev->le_scan_restart);
hci_req_init(&req, hdev);
hci_req_add_le_scan_disable(&req);
......@@ -2836,6 +2883,74 @@ static void le_scan_disable_work(struct work_struct *work)
BT_ERR("Disable LE scanning request failed: err %d", err);
}
static void le_scan_restart_work_complete(struct hci_dev *hdev, u8 status,
u16 opcode)
{
unsigned long timeout, duration, scan_start, now;
BT_DBG("%s", hdev->name);
if (status) {
BT_ERR("Failed to restart LE scan: status %d", status);
return;
}
if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
!hdev->discovery.scan_start)
return;
/* When the scan was started, hdev->le_scan_disable has been queued
* after duration from scan_start. During scan restart this job
* has been canceled, and we need to queue it again after proper
* timeout, to make sure that scan does not run indefinitely.
*/
duration = hdev->discovery.scan_duration;
scan_start = hdev->discovery.scan_start;
now = jiffies;
if (now - scan_start <= duration) {
int elapsed;
if (now >= scan_start)
elapsed = now - scan_start;
else
elapsed = ULONG_MAX - scan_start + now;
timeout = duration - elapsed;
} else {
timeout = 0;
}
queue_delayed_work(hdev->workqueue,
&hdev->le_scan_disable, timeout);
}
static void le_scan_restart_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
le_scan_restart.work);
struct hci_request req;
struct hci_cp_le_set_scan_enable cp;
int err;
BT_DBG("%s", hdev->name);
/* If controller is not scanning we are done. */
if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
return;
hci_req_init(&req, hdev);
hci_req_add_le_scan_disable(&req);
memset(&cp, 0, sizeof(cp));
cp.enable = LE_SCAN_ENABLE;
cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
err = hci_req_run(&req, le_scan_restart_work_complete);
if (err)
BT_ERR("Restart LE scan request failed: err %d", err);
}
/* Copy the Identity Address of the controller.
*
* If the controller has a public BD_ADDR, then by default use that one.
......@@ -2927,10 +3042,12 @@ struct hci_dev *hci_alloc_dev(void)
INIT_WORK(&hdev->cmd_work, hci_cmd_work);
INIT_WORK(&hdev->tx_work, hci_tx_work);
INIT_WORK(&hdev->power_on, hci_power_on);
INIT_WORK(&hdev->error_reset, hci_error_reset);
INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
skb_queue_head_init(&hdev->rx_q);
skb_queue_head_init(&hdev->cmd_q);
......@@ -3100,8 +3217,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
rfkill_destroy(hdev->rfkill);
}
smp_unregister(hdev);
device_del(&hdev->dev);
debugfs_remove_recursive(hdev->debugfs);
......
......@@ -156,6 +156,35 @@ static const struct file_operations uuids_fops = {
.release = single_release,
};
static int remote_oob_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
struct oob_data *data;
hci_dev_lock(hdev);
list_for_each_entry(data, &hdev->remote_oob_data, list) {
seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n",
&data->bdaddr, data->bdaddr_type, data->present,
16, data->hash192, 16, data->rand192,
16, data->hash256, 19, data->rand256);
}
hci_dev_unlock(hdev);
return 0;
}
static int remote_oob_open(struct inode *inode, struct file *file)
{
return single_open(file, remote_oob_show, inode->i_private);
}
static const struct file_operations remote_oob_fops = {
.open = remote_oob_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int conn_info_min_age_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
......@@ -212,6 +241,24 @@ static int conn_info_max_age_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
conn_info_max_age_set, "%llu\n");
static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static const struct file_operations use_debug_keys_fops = {
.open = simple_open,
.read = use_debug_keys_read,
.llseek = default_llseek,
};
static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
......@@ -238,17 +285,26 @@ void hci_debugfs_create_common(struct hci_dev *hdev)
&hdev->manufacturer);
debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
&hdev->hw_error_code);
debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
&device_list_fops);
debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
&blacklist_fops);
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
debugfs_create_file("remote_oob", 0400, hdev->debugfs, hdev,
&remote_oob_fops);
debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
&conn_info_min_age_fops);
debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
&conn_info_max_age_fops);
if (lmp_ssp_capable(hdev) || lmp_le_capable(hdev))
debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
hdev, &use_debug_keys_fops);
if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
hdev, &sc_only_mode_fops);
......@@ -354,6 +410,24 @@ static int voice_setting_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
NULL, "0x%4.4llx\n");
static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static const struct file_operations ssp_debug_mode_fops = {
.open = simple_open,
.read = ssp_debug_mode_read,
.llseek = default_llseek,
};
static int auto_accept_delay_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
......@@ -474,9 +548,12 @@ void hci_debugfs_create_bredr(struct hci_dev *hdev)
debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev,
&voice_setting_fops);
if (lmp_ssp_capable(hdev))
if (lmp_ssp_capable(hdev)) {
debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs,
hdev, &ssp_debug_mode_fops);
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops);
}
if (lmp_sniff_capable(hdev)) {
debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
......
......@@ -36,6 +36,9 @@
#include "amp.h"
#include "smp.h"
#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00"
/* Handle HCI Event packets */
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -197,7 +200,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
/* Reset all non-persistent flags */
hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
hdev->discovery.state = DISCOVERY_STOPPED;
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hdev->inq_tx_power = HCI_TX_POWER_INVALID;
hdev->adv_tx_power = HCI_TX_POWER_INVALID;
......@@ -525,9 +529,7 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
hdev->features[1][0] &= ~LMP_HOST_SC;
}
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_sc_enable_complete(hdev, sent->support, status);
else if (!status) {
if (!test_bit(HCI_MGMT, &hdev->dev_flags) && !status) {
if (sent->support)
set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
else
......@@ -1487,6 +1489,21 @@ static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev);
}
static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
u8 status = *((u8 *) skb->data);
u8 *mode;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
if (mode)
hdev->ssp_debug_mode = *mode;
}
static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%2.2x", hdev->name, status);
......@@ -2669,7 +2686,8 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
if (conn->state != BT_CONFIG)
goto unlock;
if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
if (!ev->status && lmp_ext_feat_capable(hdev) &&
lmp_ext_feat_capable(conn)) {
struct hci_cp_read_remote_ext_features cp;
cp.handle = ev->handle;
cp.page = 0x01;
......@@ -2980,6 +2998,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_read_tx_power(hdev, skb);
break;
case HCI_OP_WRITE_SSP_DEBUG_MODE:
hci_cc_write_ssp_debug_mode(hdev, skb);
break;
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
......@@ -3098,7 +3120,9 @@ static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_hardware_error *ev = (void *) skb->data;
BT_ERR("%s hardware error 0x%2.2x", hdev->name, ev->code);
hdev->hw_error_code = ev->code;
queue_work(hdev->req_workqueue, &hdev->error_reset);
}
static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -3857,6 +3881,52 @@ static u8 hci_get_auth_req(struct hci_conn *conn)
return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
}
static u8 bredr_oob_data_present(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct oob_data *data;
data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
if (!data)
return 0x00;
if (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) {
if (bredr_sc_enabled(hdev)) {
/* When Secure Connections is enabled, then just
* return the present value stored with the OOB
* data. The stored value contains the right present
* information. However it can only be trusted when
* not in Secure Connection Only mode.
*/
if (!test_bit(HCI_SC_ONLY, &hdev->dev_flags))
return data->present;
/* When Secure Connections Only mode is enabled, then
* the P-256 values are required. If they are not
* available, then do not declare that OOB data is
* present.
*/
if (!memcmp(data->rand256, ZERO_KEY, 16) ||
!memcmp(data->hash256, ZERO_KEY, 16))
return 0x00;
return 0x02;
}
/* When Secure Connections is not enabled or actually
* not supported by the hardware, then check that if
* P-192 data values are present.
*/
if (!memcmp(data->rand192, ZERO_KEY, 16) ||
!memcmp(data->hash192, ZERO_KEY, 16))
return 0x00;
return 0x01;
}
return 0x00;
}
static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_io_capa_request *ev = (void *) skb->data;
......@@ -3908,12 +3978,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->auth_type &= HCI_AT_NO_BONDING_MITM;
cp.authentication = conn->auth_type;
if (hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR) &&
(conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
cp.oob_data = 0x01;
else
cp.oob_data = 0x00;
cp.oob_data = bredr_oob_data_present(conn);
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
sizeof(cp), &cp);
......@@ -4165,33 +4230,39 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
goto unlock;
data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
if (data) {
if (bredr_sc_enabled(hdev)) {
struct hci_cp_remote_oob_ext_data_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
if (!data) {
struct hci_cp_remote_oob_data_neg_reply cp;
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
sizeof(cp), &cp);
} else {
struct hci_cp_remote_oob_data_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
sizeof(cp), &cp);
goto unlock;
}
bacpy(&cp.bdaddr, &ev->bdaddr);
memcpy(cp.hash, data->hash192, sizeof(cp.hash));
memcpy(cp.rand, data->rand192, sizeof(cp.rand));
if (bredr_sc_enabled(hdev)) {
struct hci_cp_remote_oob_ext_data_reply cp;
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
sizeof(cp), &cp);
bacpy(&cp.bdaddr, &ev->bdaddr);
if (test_bit(HCI_SC_ONLY, &hdev->dev_flags)) {
memset(cp.hash192, 0, sizeof(cp.hash192));
memset(cp.rand192, 0, sizeof(cp.rand192));
} else {
memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
}
memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
sizeof(cp), &cp);
} else {
struct hci_cp_remote_oob_data_neg_reply cp;
struct hci_cp_remote_oob_data_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
memcpy(cp.hash, data->hash192, sizeof(cp.hash));
memcpy(cp.rand, data->rand192, sizeof(cp.rand));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
sizeof(cp), &cp);
}
......
......@@ -302,7 +302,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
int flags)
{
DECLARE_WAITQUEUE(wait, current);
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *nsk;
long timeo;
int err = 0;
......@@ -316,8 +316,6 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break;
......@@ -338,10 +336,11 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
}
release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock_nested(sk, L2CAP_NESTING_PARENT);
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
......
......@@ -131,6 +131,9 @@ static const u16 mgmt_events[] = {
#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00"
struct pending_cmd {
struct list_head list;
u16 opcode;
......@@ -3633,10 +3636,16 @@ static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev,
static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_addr_info *addr = data;
int err;
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));
hci_dev_lock(hdev);
if (len == MGMT_ADD_REMOTE_OOB_DATA_SIZE) {
......@@ -3663,28 +3672,53 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
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;
u8 *rand192, *hash192, *rand256, *hash256;
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));
goto unlock;
}
if (bdaddr_type_is_le(cp->addr.type)) {
/* Enforce zero-valued 192-bit parameters as
* long as legacy SMP OOB isn't implemented.
*/
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));
goto unlock;
}
rand192 = NULL;
hash192 = NULL;
} else {
rand192 = cp->rand192;
hash192 = cp->hash192;
/* In case one of the P-192 values is set to zero,
* then just disable OOB data for P-192.
*/
if (!memcmp(cp->rand192, ZERO_KEY, 16) ||
!memcmp(cp->hash192, ZERO_KEY, 16)) {
rand192 = NULL;
hash192 = NULL;
} else {
rand192 = cp->rand192;
hash192 = cp->hash192;
}
}
/* In case one of the P-256 values is set to zero, then just
* disable OOB data for P-256.
*/
if (!memcmp(cp->rand256, ZERO_KEY, 16) ||
!memcmp(cp->hash256, ZERO_KEY, 16)) {
rand256 = NULL;
hash256 = NULL;
} else {
rand256 = cp->rand256;
hash256 = cp->hash256;
}
err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr,
cp->addr.type, hash192, rand192,
cp->hash256, cp->rand256);
hash256, rand256);
if (err < 0)
status = MGMT_STATUS_FAILED;
else
......@@ -3862,6 +3896,9 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status,
hci_discovery_set_state(hdev, DISCOVERY_FINDING);
/* If the scan involves LE scan, pick proper timeout to schedule
* hdev->le_scan_disable that will stop it.
*/
switch (hdev->discovery.type) {
case DISCOV_TYPE_LE:
timeout = msecs_to_jiffies(DISCOV_LE_TIMEOUT);
......@@ -3878,9 +3915,23 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status,
break;
}
if (timeout)
if (timeout) {
/* When service discovery is used and the controller has
* a strict duplicate filter, it is important to remember
* the start and duration of the scan. This is required
* for restarting scanning during the discovery phase.
*/
if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER,
&hdev->quirks) &&
(hdev->discovery.uuid_count > 0 ||
hdev->discovery.rssi != HCI_RSSI_INVALID)) {
hdev->discovery.scan_start = jiffies;
hdev->discovery.scan_duration = timeout;
}
queue_delayed_work(hdev->workqueue,
&hdev->le_scan_disable, timeout);
}
unlock:
hci_dev_unlock(hdev);
......@@ -4691,9 +4742,16 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
* Dual-mode controllers shall operate with the public
* address as its identity address for BR/EDR and LE. So
* reject the attempt to create an invalid configuration.
*
* The same restrictions applies when secure connections
* has been enabled. For BR/EDR this is a controller feature
* while for LE it is a host stack feature. This means that
* 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) &&
bacmp(&hdev->static_addr, BDADDR_ANY)) {
(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);
goto unlock;
......@@ -4736,11 +4794,57 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
return err;
}
static void sc_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
{
struct pending_cmd *cmd;
struct mgmt_mode *cp;
BT_DBG("%s status %u", hdev->name, status);
hci_dev_lock(hdev);
cmd = mgmt_pending_find(MGMT_OP_SET_SECURE_CONN, hdev);
if (!cmd)
goto unlock;
if (status) {
cmd_status(cmd->sk, cmd->index, cmd->opcode,
mgmt_status(status));
goto remove;
}
cp = cmd->param;
switch (cp->val) {
case 0x00:
clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
break;
case 0x01:
set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
break;
case 0x02:
set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
set_bit(HCI_SC_ONLY, &hdev->dev_flags);
break;
}
send_settings_rsp(cmd->sk, MGMT_OP_SET_SECURE_CONN, hdev);
new_settings(hdev, cmd->sk);
remove:
mgmt_pending_remove(cmd);
unlock:
hci_dev_unlock(hdev);
}
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 hci_request req;
u8 val;
int err;
......@@ -4751,6 +4855,12 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
MGMT_STATUS_NOT_SUPPORTED);
if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags) &&
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);
if (cp->val != 0x00 && cp->val != 0x01 && cp->val != 0x02)
return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
MGMT_STATUS_INVALID_PARAMS);
......@@ -4804,17 +4914,14 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
goto failed;
}
err = hci_send_cmd(hdev, HCI_OP_WRITE_SC_SUPPORT, 1, &val);
hci_req_init(&req, hdev);
hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, 1, &val);
err = hci_req_run(&req, sc_enable_complete);
if (err < 0) {
mgmt_pending_remove(cmd);
goto failed;
}
if (cp->val == 0x02)
set_bit(HCI_SC_ONLY, &hdev->dev_flags);
else
clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
failed:
hci_dev_unlock(hdev);
return err;
......@@ -6262,14 +6369,16 @@ static int powered_update_hci(struct hci_dev *hdev)
if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
!lmp_host_ssp_capable(hdev)) {
u8 ssp = 1;
u8 mode = 0x01;
hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
}
hci_req_add(&req, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
u8 sc = 0x01;
hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT, sizeof(sc), &sc);
if (bredr_sc_enabled(hdev) && !lmp_host_sc_capable(hdev)) {
u8 support = 0x01;
hci_req_add(&req, HCI_OP_WRITE_SC_SUPPORT,
sizeof(support), &support);
}
}
if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
......@@ -6989,43 +7098,6 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
hci_req_run(&req, NULL);
}
void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
{
struct cmd_lookup match = { NULL, hdev };
bool changed = false;
if (status) {
u8 mgmt_err = mgmt_status(status);
if (enable) {
if (test_and_clear_bit(HCI_SC_ENABLED,
&hdev->dev_flags))
new_settings(hdev, NULL);
clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
}
mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
cmd_status_rsp, &mgmt_err);
return;
}
if (enable) {
changed = !test_and_set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
} else {
changed = test_and_clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
clear_bit(HCI_SC_ONLY, &hdev->dev_flags);
}
mgmt_pending_foreach(MGMT_OP_SET_SECURE_CONN, hdev,
settings_rsp, &match);
if (changed)
new_settings(hdev, match.sk);
if (match.sk)
sock_put(match.sk);
}
static void sk_lookup(struct pending_cmd *cmd, void *data)
{
struct cmd_lookup *match = data;
......@@ -7096,28 +7168,21 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
cmd_status(cmd->sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA,
mgmt_status(status));
} else {
if (bredr_sc_enabled(hdev) && hash256 && rand256) {
struct mgmt_rp_read_local_oob_ext_data rp;
struct mgmt_rp_read_local_oob_data rp;
size_t rp_size = sizeof(rp);
memcpy(rp.hash192, hash192, sizeof(rp.hash192));
memcpy(rp.rand192, rand192, sizeof(rp.rand192));
memcpy(rp.hash192, hash192, sizeof(rp.hash192));
memcpy(rp.rand192, rand192, sizeof(rp.rand192));
if (bredr_sc_enabled(hdev) && hash256 && rand256) {
memcpy(rp.hash256, hash256, sizeof(rp.hash256));
memcpy(rp.rand256, rand256, sizeof(rp.rand256));
cmd_complete(cmd->sk, hdev->id,
MGMT_OP_READ_LOCAL_OOB_DATA, 0,
&rp, sizeof(rp));
} else {
struct mgmt_rp_read_local_oob_data rp;
memcpy(rp.hash, hash192, sizeof(rp.hash));
memcpy(rp.rand, rand192, sizeof(rp.rand));
cmd_complete(cmd->sk, hdev->id,
MGMT_OP_READ_LOCAL_OOB_DATA, 0,
&rp, sizeof(rp));
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_pending_remove(cmd);
......@@ -7190,6 +7255,21 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
return false;
}
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))
return;
if (time_after(jiffies + DISCOV_LE_RESTART_DELAY,
hdev->discovery.scan_start +
hdev->discovery.scan_duration))
return;
queue_delayed_work(hdev->workqueue, &hdev->le_scan_restart,
DISCOV_LE_RESTART_DELAY);
}
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)
......@@ -7212,14 +7292,18 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
/* When using service discovery with a RSSI threshold, then check
* if such a RSSI threshold is specified. If a RSSI threshold has
* been specified, then all results with a RSSI smaller than the
* RSSI threshold will be dropped.
* 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 < hdev->discovery.rssi || rssi == HCI_RSSI_INVALID))
(rssi == HCI_RSSI_INVALID ||
(rssi < hdev->discovery.rssi &&
!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks))))
return;
/* Make sure that the buffer is big enough. The 5 extra bytes
......@@ -7238,7 +7322,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
* However when using service discovery, the value 127 will be
* returned when the RSSI is not available.
*/
if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi)
if (rssi == HCI_RSSI_INVALID && !hdev->discovery.report_invalid_rssi &&
link_type == ACL_LINK)
rssi = 0;
bacpy(&ev->addr.bdaddr, bdaddr);
......@@ -7253,12 +7338,20 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
* kept and checking possible scan response data
* will be skipped.
*/
if (hdev->discovery.uuid_count > 0)
if (hdev->discovery.uuid_count > 0) {
match = eir_has_uuids(eir, eir_len,
hdev->discovery.uuid_count,
hdev->discovery.uuids);
else
/* 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;
......@@ -7291,6 +7384,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
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);
}
/* Append scan response data to event */
......@@ -7304,6 +7405,14 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
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;
......
......@@ -468,7 +468,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
{
DECLARE_WAITQUEUE(wait, current);
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *nsk;
long timeo;
int err = 0;
......@@ -487,8 +487,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break;
......@@ -509,10 +507,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
}
release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
......
......@@ -618,7 +618,7 @@ static int sco_sock_listen(struct socket *sock, int backlog)
static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
{
DECLARE_WAITQUEUE(wait, current);
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *ch;
long timeo;
int err = 0;
......@@ -632,8 +632,6 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break;
......@@ -654,10 +652,10 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
}
release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock(sk);
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
......
......@@ -620,7 +620,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
bdaddr_type);
if (oob_data) {
if (oob_data && oob_data->present) {
set_bit(SMP_FLAG_OOB, &smp->flags);
oob_flag = SMP_OOB_PRESENT;
memcpy(smp->rr, oob_data->rand256, 16);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册