Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
This commit is contained in:
Коммит
bd6fb31fd3
|
@ -27,6 +27,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/usb.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
||||
#define VERSION "1.0"
|
||||
|
@ -50,12 +51,12 @@
|
|||
#define ATH3K_NAME_LEN 0xFF
|
||||
|
||||
struct ath3k_version {
|
||||
unsigned int rom_version;
|
||||
unsigned int build_version;
|
||||
unsigned int ram_version;
|
||||
unsigned char ref_clock;
|
||||
unsigned char reserved[0x07];
|
||||
};
|
||||
__le32 rom_version;
|
||||
__le32 build_version;
|
||||
__le32 ram_version;
|
||||
__u8 ref_clock;
|
||||
__u8 reserved[7];
|
||||
} __packed;
|
||||
|
||||
static const struct usb_device_id ath3k_table[] = {
|
||||
/* Atheros AR3011 */
|
||||
|
@ -349,7 +350,8 @@ static int ath3k_load_patch(struct usb_device *udev)
|
|||
unsigned char fw_state;
|
||||
char filename[ATH3K_NAME_LEN] = {0};
|
||||
const struct firmware *firmware;
|
||||
struct ath3k_version fw_version, pt_version;
|
||||
struct ath3k_version fw_version;
|
||||
__u32 pt_rom_version, pt_build_version;
|
||||
int ret;
|
||||
|
||||
ret = ath3k_get_state(udev, &fw_state);
|
||||
|
@ -370,7 +372,7 @@ static int ath3k_load_patch(struct usb_device *udev)
|
|||
}
|
||||
|
||||
snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
|
||||
le32_to_cpu(fw_version.rom_version));
|
||||
le32_to_cpu(fw_version.rom_version));
|
||||
|
||||
ret = request_firmware(&firmware, filename, &udev->dev);
|
||||
if (ret < 0) {
|
||||
|
@ -378,12 +380,13 @@ static int ath3k_load_patch(struct usb_device *udev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
|
||||
pt_version.build_version = *(int *)
|
||||
(firmware->data + firmware->size - 4);
|
||||
pt_rom_version = get_unaligned_le32(firmware->data +
|
||||
firmware->size - 8);
|
||||
pt_build_version = get_unaligned_le32(firmware->data +
|
||||
firmware->size - 4);
|
||||
|
||||
if ((pt_version.rom_version != fw_version.rom_version) ||
|
||||
(pt_version.build_version <= fw_version.build_version)) {
|
||||
if (pt_rom_version != le32_to_cpu(fw_version.rom_version) ||
|
||||
pt_build_version <= le32_to_cpu(fw_version.build_version)) {
|
||||
BT_ERR("Patch file version did not match with firmware");
|
||||
release_firmware(firmware);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -91,6 +91,7 @@ struct btmrvl_private {
|
|||
|
||||
/* Vendor specific Bluetooth commands */
|
||||
#define BT_CMD_PSCAN_WIN_REPORT_ENABLE 0xFC03
|
||||
#define BT_CMD_SET_BDADDR 0xFC22
|
||||
#define BT_CMD_AUTO_SLEEP_MODE 0xFC23
|
||||
#define BT_CMD_HOST_SLEEP_CONFIG 0xFC59
|
||||
#define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A
|
||||
|
|
|
@ -539,6 +539,29 @@ static int btmrvl_setup(struct hci_dev *hdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
long ret;
|
||||
u8 buf[8];
|
||||
|
||||
buf[0] = MRVL_VENDOR_PKT;
|
||||
buf[1] = sizeof(bdaddr_t);
|
||||
memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
|
||||
|
||||
skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
BT_ERR("%s: changing btmrvl device address failed (%ld)",
|
||||
hdev->name, ret);
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the event generated by firmware, rx data
|
||||
* received from firmware, and tx data sent from kernel.
|
||||
|
@ -632,6 +655,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
|
|||
hdev->flush = btmrvl_flush;
|
||||
hdev->send = btmrvl_send_frame;
|
||||
hdev->setup = btmrvl_setup;
|
||||
hdev->set_bdaddr = btmrvl_set_bdaddr;
|
||||
|
||||
hdev->dev_type = priv->btmrvl_dev.dev_type;
|
||||
|
||||
|
|
|
@ -1169,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
priv = card->priv;
|
||||
hcidev = priv->btmrvl_dev.hcidev;
|
||||
BT_DBG("%s: SDIO suspend", hcidev->name);
|
||||
hci_suspend_dev(hcidev);
|
||||
skb_queue_purge(&priv->adapter->tx_queue);
|
||||
|
||||
if (priv->adapter->hs_state != HS_ACTIVATED) {
|
||||
if (btmrvl_enable_hs(priv)) {
|
||||
|
@ -1176,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev)
|
|||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
hcidev = priv->btmrvl_dev.hcidev;
|
||||
BT_DBG("%s: SDIO suspend", hcidev->name);
|
||||
hci_suspend_dev(hcidev);
|
||||
skb_queue_purge(&priv->adapter->tx_queue);
|
||||
|
||||
priv->adapter->is_suspended = true;
|
||||
|
||||
|
@ -1221,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
priv->adapter->is_suspended = false;
|
||||
hcidev = priv->btmrvl_dev.hcidev;
|
||||
BT_DBG("%s: SDIO resume", hcidev->name);
|
||||
hci_resume_dev(hcidev);
|
||||
priv->hw_wakeup_firmware(priv);
|
||||
priv->adapter->hs_state = HS_DEACTIVATED;
|
||||
hcidev = priv->btmrvl_dev.hcidev;
|
||||
BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
|
||||
priv->adapter->is_suspended = false;
|
||||
BT_DBG("%s: SDIO resume", hcidev->name);
|
||||
hci_resume_dev(hcidev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ static struct usb_driver btusb_driver;
|
|||
#define BTUSB_INTEL 0x100
|
||||
#define BTUSB_INTEL_BOOT 0x200
|
||||
#define BTUSB_BCM_PATCHRAM 0x400
|
||||
#define BTUSB_MARVELL 0x800
|
||||
|
||||
static const struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
|
@ -113,6 +114,9 @@ static const struct usb_device_id btusb_table[] = {
|
|||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
|
||||
.driver_info = BTUSB_BCM_PATCHRAM },
|
||||
|
||||
/* ASUSTek Computer - Broadcom based */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0b05, 0xff, 0x01, 0x01) },
|
||||
|
||||
/* Belkin F8065bf - Broadcom based */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
|
||||
|
||||
|
@ -242,6 +246,10 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
|
||||
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
|
||||
|
||||
/* Marvell device */
|
||||
{ USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
|
||||
{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -1455,6 +1463,29 @@ static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
|
||||
const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 buf[8];
|
||||
long ret;
|
||||
|
||||
buf[0] = 0xfe;
|
||||
buf[1] = sizeof(bdaddr_t);
|
||||
memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
BT_ERR("%s: changing Marvell device address failed (%ld)",
|
||||
hdev->name, ret);
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
|
||||
|
||||
static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
|
||||
|
@ -1766,6 +1797,9 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
hdev->set_bdaddr = btusb_set_bdaddr_intel;
|
||||
}
|
||||
|
||||
if (id->driver_info & BTUSB_MARVELL)
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_marvell;
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL_BOOT)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
|
|
|
@ -401,6 +401,9 @@ enum {
|
|||
/* The core spec defines 127 as the "not available" value */
|
||||
#define HCI_TX_POWER_INVALID 127
|
||||
|
||||
#define HCI_ROLE_MASTER 0x00
|
||||
#define HCI_ROLE_SLAVE 0x01
|
||||
|
||||
/* Extended Inquiry Response field types */
|
||||
#define EIR_FLAGS 0x01 /* flags */
|
||||
#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
|
||||
|
@ -1713,9 +1716,6 @@ struct hci_ev_sync_train_complete {
|
|||
|
||||
#define HCI_EV_SLAVE_PAGE_RESP_TIMEOUT 0x54
|
||||
|
||||
/* Low energy meta events */
|
||||
#define LE_CONN_ROLE_MASTER 0x00
|
||||
|
||||
#define HCI_EV_LE_CONN_COMPLETE 0x01
|
||||
struct hci_ev_le_conn_complete {
|
||||
__u8 status;
|
||||
|
|
|
@ -83,6 +83,7 @@ struct hci_conn_hash {
|
|||
unsigned int amp_num;
|
||||
unsigned int sco_num;
|
||||
unsigned int le_num;
|
||||
unsigned int le_num_slave;
|
||||
};
|
||||
|
||||
struct bdaddr_list {
|
||||
|
@ -371,6 +372,7 @@ struct hci_conn {
|
|||
__u16 state;
|
||||
__u8 mode;
|
||||
__u8 type;
|
||||
__u8 role;
|
||||
bool out;
|
||||
__u8 attempt;
|
||||
__u8 dev_class[3];
|
||||
|
@ -540,12 +542,12 @@ enum {
|
|||
HCI_CONN_POWER_SAVE,
|
||||
HCI_CONN_REMOTE_OOB,
|
||||
HCI_CONN_FLUSH_KEY,
|
||||
HCI_CONN_MASTER,
|
||||
HCI_CONN_ENCRYPT,
|
||||
HCI_CONN_AUTH,
|
||||
HCI_CONN_SECURE,
|
||||
HCI_CONN_FIPS,
|
||||
HCI_CONN_STK_ENCRYPT,
|
||||
HCI_CONN_AUTH_INITIATOR,
|
||||
};
|
||||
|
||||
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
|
||||
|
@ -575,6 +577,8 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
|
|||
break;
|
||||
case LE_LINK:
|
||||
h->le_num++;
|
||||
if (c->role == HCI_ROLE_SLAVE)
|
||||
h->le_num_slave++;
|
||||
break;
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
|
@ -599,6 +603,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
|
|||
break;
|
||||
case LE_LINK:
|
||||
h->le_num--;
|
||||
if (c->role == HCI_ROLE_SLAVE)
|
||||
h->le_num_slave--;
|
||||
break;
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
|
@ -695,7 +701,8 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason);
|
|||
bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
|
||||
void hci_sco_setup(struct hci_conn *conn, __u8 status);
|
||||
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
u8 role);
|
||||
int hci_conn_del(struct hci_conn *conn);
|
||||
void hci_conn_hash_flush(struct hci_dev *hdev);
|
||||
void hci_conn_check_pending(struct hci_dev *hdev);
|
||||
|
@ -707,14 +714,15 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
|
|||
|
||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level, u16 conn_timeout,
|
||||
bool master);
|
||||
u8 role);
|
||||
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 sec_level, u8 auth_type);
|
||||
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
__u16 setting);
|
||||
int hci_conn_check_link_mode(struct hci_conn *conn);
|
||||
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
|
||||
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
|
||||
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
|
||||
bool initiator);
|
||||
int hci_conn_change_link_key(struct hci_conn *conn);
|
||||
int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
|
||||
|
||||
|
@ -881,12 +889,12 @@ struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
|
|||
bdaddr_t *bdaddr, u8 *val, u8 type,
|
||||
u8 pin_len, bool *persistent);
|
||||
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
|
||||
bool master);
|
||||
u8 role);
|
||||
struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 addr_type, u8 type, u8 authenticated,
|
||||
u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand);
|
||||
struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 addr_type, bool master);
|
||||
u8 addr_type, u8 role);
|
||||
int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
|
||||
void hci_smp_ltks_clear(struct hci_dev *hdev);
|
||||
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
|
||||
|
|
|
@ -905,7 +905,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||
bdaddr_t *dst, u8 dst_type);
|
||||
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
|
||||
void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
|
||||
int l2cap_chan_check_security(struct l2cap_chan *chan);
|
||||
int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
|
||||
void l2cap_chan_set_defaults(struct l2cap_chan *chan);
|
||||
int l2cap_ertm_init(struct l2cap_chan *chan);
|
||||
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
|
||||
|
|
|
@ -113,8 +113,9 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
|
|||
{
|
||||
bdaddr_t *dst = &mgr->l2cap_conn->hcon->dst;
|
||||
struct hci_conn *hcon;
|
||||
u8 role = out ? HCI_ROLE_MASTER : HCI_ROLE_SLAVE;
|
||||
|
||||
hcon = hci_conn_add(hdev, AMP_LINK, dst);
|
||||
hcon = hci_conn_add(hdev, AMP_LINK, dst, role);
|
||||
if (!hcon)
|
||||
return NULL;
|
||||
|
||||
|
@ -125,7 +126,6 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
|
|||
hcon->handle = __next_handle(mgr);
|
||||
hcon->remote_id = remote_id;
|
||||
hcon->amp_mgr = amp_mgr_get(mgr);
|
||||
hcon->out = out;
|
||||
|
||||
return hcon;
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
|
|||
/* AMP crypto key generation interface */
|
||||
static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output)
|
||||
{
|
||||
int ret = 0;
|
||||
struct crypto_shash *tfm;
|
||||
int ret;
|
||||
|
||||
if (!ksize)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -66,8 +66,7 @@ static void hci_acl_create_connection(struct hci_conn *conn)
|
|||
|
||||
conn->state = BT_CONNECT;
|
||||
conn->out = true;
|
||||
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
conn->role = HCI_ROLE_MASTER;
|
||||
|
||||
conn->attempt++;
|
||||
|
||||
|
@ -335,7 +334,7 @@ static void hci_conn_timeout(struct work_struct *work)
|
|||
* event handling and hci_clock_offset_evt function.
|
||||
*/
|
||||
if (conn->type == ACL_LINK &&
|
||||
test_bit(HCI_CONN_MASTER, &conn->flags)) {
|
||||
conn->role == HCI_ROLE_MASTER) {
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
struct hci_cp_read_clock_offset cp;
|
||||
|
||||
|
@ -422,13 +421,14 @@ static void le_conn_timeout(struct work_struct *work)
|
|||
hci_le_create_connection_cancel(conn);
|
||||
}
|
||||
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
u8 role)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
|
||||
BT_DBG("%s dst %pMR", hdev->name, dst);
|
||||
|
||||
conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
|
||||
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
||||
if (!conn)
|
||||
return NULL;
|
||||
|
||||
|
@ -436,6 +436,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
|
|||
bacpy(&conn->src, &hdev->bdaddr);
|
||||
conn->hdev = hdev;
|
||||
conn->type = type;
|
||||
conn->role = role;
|
||||
conn->mode = HCI_CM_ACTIVE;
|
||||
conn->state = BT_OPEN;
|
||||
conn->auth_type = HCI_AT_GENERAL_BONDING;
|
||||
|
@ -448,6 +449,9 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
|
|||
set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
|
||||
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
|
||||
|
||||
if (conn->role == HCI_ROLE_MASTER)
|
||||
conn->out = true;
|
||||
|
||||
switch (type) {
|
||||
case ACL_LINK:
|
||||
conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
|
||||
|
@ -698,7 +702,7 @@ static void hci_req_directed_advertising(struct hci_request *req,
|
|||
|
||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level, u16 conn_timeout,
|
||||
bool master)
|
||||
u8 role)
|
||||
{
|
||||
struct hci_conn_params *params;
|
||||
struct hci_conn *conn;
|
||||
|
@ -747,7 +751,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
dst_type = ADDR_LE_DEV_RANDOM;
|
||||
}
|
||||
|
||||
conn = hci_conn_add(hdev, LE_LINK, dst);
|
||||
conn = hci_conn_add(hdev, LE_LINK, dst, role);
|
||||
if (!conn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -771,7 +775,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
}
|
||||
|
||||
/* If requested to connect as slave use directed advertising */
|
||||
if (!master) {
|
||||
if (conn->role == HCI_ROLE_SLAVE) {
|
||||
/* If we're active scanning most controllers are unable
|
||||
* to initiate advertising. Simply reject the attempt.
|
||||
*/
|
||||
|
@ -786,9 +790,6 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
goto create_conn;
|
||||
}
|
||||
|
||||
conn->out = true;
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
|
||||
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
|
||||
if (params) {
|
||||
conn->le_conn_min_interval = params->conn_min_interval;
|
||||
|
@ -833,11 +834,11 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
|||
struct hci_conn *acl;
|
||||
|
||||
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||
if (!acl) {
|
||||
acl = hci_conn_add(hdev, ACL_LINK, dst);
|
||||
acl = hci_conn_add(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
|
||||
if (!acl)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
@ -866,7 +867,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
|||
|
||||
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
|
||||
if (!sco) {
|
||||
sco = hci_conn_add(hdev, type, dst);
|
||||
sco = hci_conn_add(hdev, type, dst, HCI_ROLE_MASTER);
|
||||
if (!sco) {
|
||||
hci_conn_drop(acl);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -972,7 +973,8 @@ static void hci_conn_encrypt(struct hci_conn *conn)
|
|||
}
|
||||
|
||||
/* Enable security */
|
||||
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
|
||||
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
|
||||
bool initiator)
|
||||
{
|
||||
BT_DBG("hcon %p", conn);
|
||||
|
||||
|
@ -1025,6 +1027,9 @@ auth:
|
|||
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
|
||||
return 0;
|
||||
|
||||
if (initiator)
|
||||
set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
|
||||
|
||||
if (!hci_conn_auth(conn, sec_level, auth_type))
|
||||
return 0;
|
||||
|
||||
|
@ -1076,7 +1081,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
|
|||
{
|
||||
BT_DBG("hcon %p", conn);
|
||||
|
||||
if (!role && test_bit(HCI_CONN_MASTER, &conn->flags))
|
||||
if (role == conn->role)
|
||||
return 1;
|
||||
|
||||
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
|
||||
|
@ -1151,7 +1156,7 @@ static u32 get_link_mode(struct hci_conn *conn)
|
|||
{
|
||||
u32 link_mode = 0;
|
||||
|
||||
if (test_bit(HCI_CONN_MASTER, &conn->flags))
|
||||
if (conn->role == HCI_ROLE_MASTER)
|
||||
link_mode |= HCI_LM_MASTER;
|
||||
|
||||
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
|
||||
|
@ -1277,7 +1282,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
|
|||
|
||||
BT_DBG("%s hcon %p", hdev->name, conn);
|
||||
|
||||
chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL);
|
||||
chan = kzalloc(sizeof(*chan), GFP_KERNEL);
|
||||
if (!chan)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -2088,7 +2088,7 @@ u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
|
|||
}
|
||||
|
||||
/* Entry not in the cache. Add new one. */
|
||||
ie = kzalloc(sizeof(struct inquiry_entry), GFP_KERNEL);
|
||||
ie = kzalloc(sizeof(*ie), GFP_KERNEL);
|
||||
if (!ie) {
|
||||
flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
|
||||
goto done;
|
||||
|
@ -3121,13 +3121,16 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool ltk_type_master(u8 type)
|
||||
static u8 ltk_role(u8 type)
|
||||
{
|
||||
return (type == SMP_LTK);
|
||||
if (type == SMP_LTK)
|
||||
return HCI_ROLE_MASTER;
|
||||
|
||||
return HCI_ROLE_SLAVE;
|
||||
}
|
||||
|
||||
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
|
||||
bool master)
|
||||
u8 role)
|
||||
{
|
||||
struct smp_ltk *k;
|
||||
|
||||
|
@ -3135,7 +3138,7 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
|
|||
if (k->ediv != ediv || k->rand != rand)
|
||||
continue;
|
||||
|
||||
if (ltk_type_master(k->type) != master)
|
||||
if (ltk_role(k->type) != role)
|
||||
continue;
|
||||
|
||||
return k;
|
||||
|
@ -3145,14 +3148,14 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
|
|||
}
|
||||
|
||||
struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
u8 addr_type, bool master)
|
||||
u8 addr_type, u8 role)
|
||||
{
|
||||
struct smp_ltk *k;
|
||||
|
||||
list_for_each_entry(k, &hdev->long_term_keys, list)
|
||||
if (addr_type == k->bdaddr_type &&
|
||||
bacmp(bdaddr, &k->bdaddr) == 0 &&
|
||||
ltk_type_master(k->type) == master)
|
||||
ltk_role(k->type) == role)
|
||||
return k;
|
||||
|
||||
return NULL;
|
||||
|
@ -3247,9 +3250,9 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
|||
u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
|
||||
{
|
||||
struct smp_ltk *key, *old_key;
|
||||
bool master = ltk_type_master(type);
|
||||
u8 role = ltk_role(type);
|
||||
|
||||
old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
|
||||
old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, role);
|
||||
if (old_key)
|
||||
key = old_key;
|
||||
else {
|
||||
|
@ -3489,7 +3492,7 @@ int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
|
|||
if (hci_bdaddr_list_lookup(list, bdaddr, type))
|
||||
return -EEXIST;
|
||||
|
||||
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
|
||||
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -3894,7 +3897,7 @@ struct hci_dev *hci_alloc_dev(void)
|
|||
{
|
||||
struct hci_dev *hdev;
|
||||
|
||||
hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
|
||||
hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
|
||||
if (!hdev)
|
||||
return NULL;
|
||||
|
||||
|
@ -5462,8 +5465,7 @@ void hci_update_background_scan(struct hci_dev *hdev)
|
|||
|
||||
hci_req_init(&req, hdev);
|
||||
|
||||
if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
|
||||
list_empty(&hdev->pend_le_conns) &&
|
||||
if (list_empty(&hdev->pend_le_conns) &&
|
||||
list_empty(&hdev->pend_le_reports)) {
|
||||
/* If there is no pending LE connections or devices
|
||||
* to be scanned for, we should stop the background
|
||||
|
|
|
@ -101,12 +101,8 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
hci_dev_lock(hdev);
|
||||
|
||||
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
|
||||
if (conn) {
|
||||
if (rp->role)
|
||||
clear_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
else
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
}
|
||||
if (conn)
|
||||
conn->role = rp->role;
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
@ -1418,11 +1414,9 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
|
|||
}
|
||||
} else {
|
||||
if (!conn) {
|
||||
conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
|
||||
if (conn) {
|
||||
conn->out = true;
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
} else
|
||||
conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr,
|
||||
HCI_ROLE_MASTER);
|
||||
if (!conn)
|
||||
BT_ERR("No memory for new connection");
|
||||
}
|
||||
}
|
||||
|
@ -1651,6 +1645,8 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
|
|||
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
|
||||
struct hci_cp_auth_requested auth_cp;
|
||||
|
||||
set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
|
||||
|
||||
auth_cp.handle = __cpu_to_le16(conn->handle);
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
|
||||
sizeof(auth_cp), &auth_cp);
|
||||
|
@ -2135,18 +2131,17 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
return;
|
||||
}
|
||||
|
||||
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) {
|
||||
if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
|
||||
!hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connection accepted */
|
||||
|
@ -2160,7 +2155,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
|
||||
&ev->bdaddr);
|
||||
if (!conn) {
|
||||
conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
|
||||
conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
|
||||
HCI_ROLE_SLAVE);
|
||||
if (!conn) {
|
||||
BT_ERR("No memory for new connection");
|
||||
hci_dev_unlock(hdev);
|
||||
|
@ -2393,6 +2389,9 @@ check_auth:
|
|||
|
||||
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
|
||||
struct hci_cp_auth_requested cp;
|
||||
|
||||
set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
|
||||
|
||||
cp.handle = __cpu_to_le16(conn->handle);
|
||||
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
|
||||
}
|
||||
|
@ -2924,12 +2923,8 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
|
||||
if (conn) {
|
||||
if (!ev->status) {
|
||||
if (ev->role)
|
||||
clear_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
else
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
}
|
||||
if (!ev->status)
|
||||
conn->role = ev->role;
|
||||
|
||||
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
|
||||
|
||||
|
@ -3123,10 +3118,11 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
hci_conn_drop(conn);
|
||||
}
|
||||
|
||||
if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
|
||||
if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags) &&
|
||||
!test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
|
||||
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
|
||||
sizeof(ev->bdaddr), &ev->bdaddr);
|
||||
else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
|
||||
} else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
|
||||
u8 secure;
|
||||
|
||||
if (conn->pending_sec_level == BT_SECURITY_HIGH)
|
||||
|
@ -3652,7 +3648,11 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
|
||||
goto unlock;
|
||||
|
||||
/* Allow pairing if we're pairable, the initiators of the
|
||||
* pairing or if the remote is not requesting bonding.
|
||||
*/
|
||||
if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
|
||||
test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
|
||||
(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
|
||||
struct hci_cp_io_capability_reply cp;
|
||||
|
||||
|
@ -3668,7 +3668,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
* except for the no-bonding case.
|
||||
*/
|
||||
if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
|
||||
cp.authentication != HCI_AT_NO_BONDING)
|
||||
conn->auth_type != HCI_AT_NO_BONDING)
|
||||
conn->auth_type |= 0x01;
|
||||
|
||||
cp.authentication = conn->auth_type;
|
||||
|
@ -3762,9 +3762,11 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
|
|||
/* If we're not the initiators request authorization to
|
||||
* proceed from user space (mgmt_user_confirm with
|
||||
* confirm_hint set to 1). The exception is if neither
|
||||
* side had MITM in which case we do auto-accept.
|
||||
* side had MITM or if the local IO capability is
|
||||
* NoInputNoOutput, in which case we do auto-accept
|
||||
*/
|
||||
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
|
||||
conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
|
||||
(loc_mitm || rem_mitm)) {
|
||||
BT_DBG("Confirming auto-accept as acceptor");
|
||||
confirm_hint = 1;
|
||||
|
@ -3878,6 +3880,9 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
|
|||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
/* Reset the authentication requirement to unknown */
|
||||
conn->remote_auth = 0xff;
|
||||
|
||||
/* To avoid duplicate auth_failed events to user space we check
|
||||
* the HCI_CONN_AUTH_PEND flag which will be set if we
|
||||
* initiated the authentication. A traditional auth_complete
|
||||
|
@ -4108,7 +4113,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
|
||||
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
|
||||
if (!conn) {
|
||||
conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
|
||||
conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role);
|
||||
if (!conn) {
|
||||
BT_ERR("No memory for new connection");
|
||||
goto unlock;
|
||||
|
@ -4116,11 +4121,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
|
||||
conn->dst_type = ev->bdaddr_type;
|
||||
|
||||
if (ev->role == LE_CONN_ROLE_MASTER) {
|
||||
conn->out = true;
|
||||
set_bit(HCI_CONN_MASTER, &conn->flags);
|
||||
}
|
||||
|
||||
/* If we didn't have a hci_conn object previously
|
||||
* but we're in master role this must be something
|
||||
* initiated using a white list. Since white list based
|
||||
|
@ -4187,14 +4187,14 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
else
|
||||
addr_type = BDADDR_LE_RANDOM;
|
||||
|
||||
/* Drop the connection if he device is blocked */
|
||||
if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) {
|
||||
hci_conn_drop(conn);
|
||||
if (ev->status) {
|
||||
hci_le_conn_failed(conn, ev->status);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (ev->status) {
|
||||
hci_le_conn_failed(conn, ev->status);
|
||||
/* Drop the connection if the device is blocked */
|
||||
if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) {
|
||||
hci_conn_drop(conn);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
@ -4260,6 +4260,12 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
|
|||
if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
|
||||
return;
|
||||
|
||||
/* Most controller will fail if we try to create new connections
|
||||
* while we have an existing one in slave role.
|
||||
*/
|
||||
if (hdev->conn_hash.le_num_slave > 0)
|
||||
return;
|
||||
|
||||
/* If we're connectable, always connect any ADV_DIRECT_IND event */
|
||||
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
|
||||
adv_type == LE_ADV_DIRECT_IND)
|
||||
|
@ -4272,9 +4278,8 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
|
|||
return;
|
||||
|
||||
connect:
|
||||
/* Request connection in master = true role */
|
||||
conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
|
||||
HCI_LE_AUTOCONN_TIMEOUT, true);
|
||||
HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER);
|
||||
if (!IS_ERR(conn))
|
||||
return;
|
||||
|
||||
|
@ -4314,14 +4319,11 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
|||
* device found events.
|
||||
*/
|
||||
if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
|
||||
struct hci_conn_params *param;
|
||||
|
||||
if (type == LE_ADV_DIRECT_IND)
|
||||
return;
|
||||
|
||||
param = hci_pend_le_action_lookup(&hdev->pend_le_reports,
|
||||
bdaddr, bdaddr_type);
|
||||
if (!param)
|
||||
if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
|
||||
bdaddr, bdaddr_type))
|
||||
return;
|
||||
|
||||
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
|
||||
|
@ -4455,7 +4457,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (conn == NULL)
|
||||
goto not_found;
|
||||
|
||||
ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
|
||||
ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->role);
|
||||
if (ltk == NULL)
|
||||
goto not_found;
|
||||
|
||||
|
@ -4530,7 +4532,7 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
|
|||
return send_conn_param_neg_reply(hdev, handle,
|
||||
HCI_ERROR_INVALID_LL_PARAMS);
|
||||
|
||||
if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
|
||||
if (hcon->role == HCI_ROLE_MASTER) {
|
||||
struct hci_conn_params *params;
|
||||
u8 store_hint;
|
||||
|
||||
|
|
|
@ -775,7 +775,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
|
|||
}
|
||||
|
||||
/* Service level security */
|
||||
int l2cap_chan_check_security(struct l2cap_chan *chan)
|
||||
int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
|
||||
{
|
||||
struct l2cap_conn *conn = chan->conn;
|
||||
__u8 auth_type;
|
||||
|
@ -785,7 +785,8 @@ int l2cap_chan_check_security(struct l2cap_chan *chan)
|
|||
|
||||
auth_type = l2cap_get_auth_type(chan);
|
||||
|
||||
return hci_conn_security(conn->hcon, chan->sec_level, auth_type);
|
||||
return hci_conn_security(conn->hcon, chan->sec_level, auth_type,
|
||||
initiator);
|
||||
}
|
||||
|
||||
static u8 l2cap_get_ident(struct l2cap_conn *conn)
|
||||
|
@ -1278,7 +1279,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
|
|||
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
|
||||
return;
|
||||
|
||||
if (l2cap_chan_check_security(chan) &&
|
||||
if (l2cap_chan_check_security(chan, true) &&
|
||||
__l2cap_no_conn_pending(chan)) {
|
||||
l2cap_start_connection(chan);
|
||||
}
|
||||
|
@ -1357,7 +1358,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|||
}
|
||||
|
||||
if (chan->state == BT_CONNECT) {
|
||||
if (!l2cap_chan_check_security(chan) ||
|
||||
if (!l2cap_chan_check_security(chan, true) ||
|
||||
!__l2cap_no_conn_pending(chan)) {
|
||||
l2cap_chan_unlock(chan);
|
||||
continue;
|
||||
|
@ -1379,7 +1380,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
|||
rsp.scid = cpu_to_le16(chan->dcid);
|
||||
rsp.dcid = cpu_to_le16(chan->scid);
|
||||
|
||||
if (l2cap_chan_check_security(chan)) {
|
||||
if (l2cap_chan_check_security(chan, false)) {
|
||||
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
|
||||
rsp.result = cpu_to_le16(L2CAP_CR_PEND);
|
||||
rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
|
||||
|
@ -1487,7 +1488,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
|
|||
* been configured for this connection. If not, then trigger
|
||||
* the connection update procedure.
|
||||
*/
|
||||
if (!test_bit(HCI_CONN_MASTER, &hcon->flags) &&
|
||||
if (hcon->role == HCI_ROLE_SLAVE &&
|
||||
(hcon->le_conn_interval < hcon->le_conn_min_interval ||
|
||||
hcon->le_conn_interval > hcon->le_conn_max_interval)) {
|
||||
struct l2cap_conn_param_update_req req;
|
||||
|
@ -3849,7 +3850,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
|
|||
chan->ident = cmd->ident;
|
||||
|
||||
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
|
||||
if (l2cap_chan_check_security(chan)) {
|
||||
if (l2cap_chan_check_security(chan, false)) {
|
||||
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
|
||||
l2cap_state_change(chan, BT_CONNECT2);
|
||||
result = L2CAP_CR_PEND;
|
||||
|
@ -5227,7 +5228,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
|
|||
u16 min, max, latency, to_multiplier;
|
||||
int err;
|
||||
|
||||
if (!test_bit(HCI_CONN_MASTER, &hcon->flags))
|
||||
if (hcon->role != HCI_ROLE_MASTER)
|
||||
return -EINVAL;
|
||||
|
||||
if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
|
||||
|
@ -6984,7 +6985,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
|
|||
if (!hchan)
|
||||
return NULL;
|
||||
|
||||
conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL);
|
||||
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
||||
if (!conn) {
|
||||
hci_chan_del(hchan);
|
||||
return NULL;
|
||||
|
@ -7093,7 +7094,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
err = -ENOTSUPP;
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -7128,7 +7129,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||
chan->dcid = cid;
|
||||
|
||||
if (bdaddr_type_is_le(dst_type)) {
|
||||
bool master;
|
||||
u8 role;
|
||||
|
||||
/* Convert from L2CAP channel address type to HCI address type
|
||||
*/
|
||||
|
@ -7137,10 +7138,13 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||
else
|
||||
dst_type = ADDR_LE_DEV_RANDOM;
|
||||
|
||||
master = !test_bit(HCI_ADVERTISING, &hdev->dev_flags);
|
||||
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
|
||||
role = HCI_ROLE_SLAVE;
|
||||
else
|
||||
role = HCI_ROLE_MASTER;
|
||||
|
||||
hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
|
||||
HCI_LE_CONN_TIMEOUT, master);
|
||||
HCI_LE_CONN_TIMEOUT, role);
|
||||
} else {
|
||||
u8 auth_type = l2cap_get_auth_type(chan);
|
||||
hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
|
||||
|
@ -7188,7 +7192,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
|||
if (hcon->state == BT_CONNECTED) {
|
||||
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
|
||||
__clear_chan_timer(chan);
|
||||
if (l2cap_chan_check_security(chan))
|
||||
if (l2cap_chan_check_security(chan, true))
|
||||
l2cap_state_change(chan, BT_CONNECTED);
|
||||
} else
|
||||
l2cap_do_start(chan);
|
||||
|
|
|
@ -279,7 +279,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
|
|||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
err = -ENOTSUPP;
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -797,7 +797,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
|
|||
} else if ((sk->sk_state == BT_CONNECT2 &&
|
||||
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
|
||||
sk->sk_state == BT_CONNECTED) {
|
||||
if (!l2cap_chan_check_security(chan))
|
||||
if (!l2cap_chan_check_security(chan, true))
|
||||
set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
|
||||
else
|
||||
sk->sk_state_change(sk);
|
||||
|
@ -1112,7 +1112,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
|
|||
l2cap_chan_close(chan, 0);
|
||||
lock_sock(sk);
|
||||
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
|
||||
!(current->flags & PF_EXITING))
|
||||
err = bt_sock_wait_state(sk, BT_CLOSED,
|
||||
sk->sk_lingertime);
|
||||
}
|
||||
|
|
|
@ -3154,9 +3154,9 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
*/
|
||||
hci_conn_params_add(hdev, &cp->addr.bdaddr, addr_type);
|
||||
|
||||
/* Request a connection with master = true role */
|
||||
conn = hci_connect_le(hdev, &cp->addr.bdaddr, addr_type,
|
||||
sec_level, HCI_LE_CONN_TIMEOUT, true);
|
||||
sec_level, HCI_LE_CONN_TIMEOUT,
|
||||
HCI_ROLE_MASTER);
|
||||
}
|
||||
|
||||
if (IS_ERR(conn)) {
|
||||
|
@ -3202,7 +3202,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
|
|||
cmd->user_data = conn;
|
||||
|
||||
if (conn->state == BT_CONNECTED &&
|
||||
hci_conn_security(conn, sec_level, auth_type))
|
||||
hci_conn_security(conn, sec_level, auth_type, true))
|
||||
pairing_complete(cmd, 0);
|
||||
|
||||
err = 0;
|
||||
|
|
|
@ -227,7 +227,8 @@ static int rfcomm_check_security(struct rfcomm_dlc *d)
|
|||
break;
|
||||
}
|
||||
|
||||
return hci_conn_security(conn->hcon, d->sec_level, auth_type);
|
||||
return hci_conn_security(conn->hcon, d->sec_level, auth_type,
|
||||
d->out);
|
||||
}
|
||||
|
||||
static void rfcomm_session_timeout(unsigned long arg)
|
||||
|
|
|
@ -918,7 +918,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
|
|||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
__rfcomm_sock_close(sk);
|
||||
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
|
||||
!(current->flags & PF_EXITING))
|
||||
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
|
||||
}
|
||||
release_sock(sk);
|
||||
|
|
|
@ -970,7 +970,8 @@ static int sco_sock_shutdown(struct socket *sock, int how)
|
|||
sco_sock_clear_timer(sk);
|
||||
__sco_sock_close(sk);
|
||||
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
|
||||
!(current->flags & PF_EXITING))
|
||||
err = bt_sock_wait_state(sk, BT_CLOSED,
|
||||
sk->sk_lingertime);
|
||||
}
|
||||
|
@ -990,7 +991,8 @@ static int sco_sock_release(struct socket *sock)
|
|||
|
||||
sco_sock_close(sk);
|
||||
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
|
||||
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
|
||||
!(current->flags & PF_EXITING)) {
|
||||
lock_sock(sk);
|
||||
err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
|
||||
release_sock(sk);
|
||||
|
|
|
@ -431,6 +431,10 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
|
|||
if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags))
|
||||
method = JUST_WORKS;
|
||||
|
||||
/* Don't bother user space with no IO capabilities */
|
||||
if (method == JUST_CFM && hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
|
||||
method = JUST_WORKS;
|
||||
|
||||
/* If Just Works, Continue with Zero TK */
|
||||
if (method == JUST_WORKS) {
|
||||
set_bit(SMP_FLAG_TK_VALID, &smp->flags);
|
||||
|
@ -445,7 +449,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
|
|||
* Confirms and the slave Enters the passkey.
|
||||
*/
|
||||
if (method == OVERLAP) {
|
||||
if (test_bit(HCI_CONN_MASTER, &hcon->flags))
|
||||
if (hcon->role == HCI_ROLE_MASTER)
|
||||
method = CFM_PASSKEY;
|
||||
else
|
||||
method = REQ_PASSKEY;
|
||||
|
@ -686,7 +690,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
if (skb->len < sizeof(*req))
|
||||
return SMP_INVALID_PARAMS;
|
||||
|
||||
if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
|
||||
if (conn->hcon->role != HCI_ROLE_SLAVE)
|
||||
return SMP_CMD_NOTSUPP;
|
||||
|
||||
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
|
||||
|
@ -755,7 +759,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
if (skb->len < sizeof(*rsp))
|
||||
return SMP_INVALID_PARAMS;
|
||||
|
||||
if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
|
||||
if (conn->hcon->role != HCI_ROLE_MASTER)
|
||||
return SMP_CMD_NOTSUPP;
|
||||
|
||||
skb_pull(skb, sizeof(*rsp));
|
||||
|
@ -849,7 +853,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
|
|||
struct hci_conn *hcon = conn->hcon;
|
||||
|
||||
key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
|
||||
hcon->out);
|
||||
hcon->role);
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
|
@ -881,7 +885,7 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
|
|||
*/
|
||||
if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags) &&
|
||||
hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
|
||||
hcon->out))
|
||||
hcon->role))
|
||||
return false;
|
||||
|
||||
if (hcon->sec_level >= sec_level)
|
||||
|
@ -903,7 +907,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
if (skb->len < sizeof(*rp))
|
||||
return SMP_INVALID_PARAMS;
|
||||
|
||||
if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
|
||||
if (hcon->role != HCI_ROLE_MASTER)
|
||||
return SMP_CMD_NOTSUPP;
|
||||
|
||||
sec_level = authreq_to_seclevel(rp->auth_req);
|
||||
|
@ -961,7 +965,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
|||
if (sec_level > hcon->pending_sec_level)
|
||||
hcon->pending_sec_level = sec_level;
|
||||
|
||||
if (test_bit(HCI_CONN_MASTER, &hcon->flags))
|
||||
if (hcon->role == HCI_ROLE_MASTER)
|
||||
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
|
||||
return 0;
|
||||
|
||||
|
@ -981,7 +985,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
|
|||
hcon->pending_sec_level > BT_SECURITY_MEDIUM)
|
||||
authreq |= SMP_AUTH_MITM;
|
||||
|
||||
if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
|
||||
if (hcon->role == HCI_ROLE_MASTER) {
|
||||
struct smp_cmd_pairing cp;
|
||||
|
||||
build_pairing_cmd(conn, &cp, NULL, authreq);
|
||||
|
@ -1185,7 +1189,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {
|
||||
err = -ENOTSUPP;
|
||||
err = -EOPNOTSUPP;
|
||||
reason = SMP_PAIRING_NOTSUPP;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1203,7 +1207,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
|
|||
!conn->smp_chan) {
|
||||
BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
|
||||
kfree_skb(skb);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче