提交 66568b39 编写于 作者: D David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
Please pull this batch of updates intended for the 3.17 stream...

This is primarily a Bluetooth pull.  Gustavo says:

"A lot of patches to 3.17. The bulk of changes here are for LE support.
The 6loWPAN over Bluetooth now has it own module, we also have support for
background auto-connection and passive scanning, Bluetooth device address
provisioning, support for reading Bluetooth clock values and LE connection
parameters plus many many fixes."

The balance is just a pull of the wireless.git tree, to avoid some
pending merge problems.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -90,7 +90,6 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0) },
{ USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x3005) },
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) },
......@@ -104,6 +103,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3432) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
......@@ -140,7 +140,6 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
......@@ -154,6 +153,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
......@@ -290,10 +290,10 @@ static int ath3k_load_fwfile(struct usb_device *udev,
sent += size;
count -= size;
while (count) {
size = min_t(uint, count, BULK_SIZE);
pipe = usb_sndbulkpipe(udev, 0x02);
while (count) {
size = min_t(uint, count, BULK_SIZE);
memcpy(send_buf, firmware->data + sent, size);
err = usb_bulk_msg(udev, pipe, send_buf, size,
......
......@@ -68,6 +68,7 @@ struct btmrvl_adapter {
u8 hs_state;
u8 wakeup_tries;
wait_queue_head_t cmd_wait_q;
wait_queue_head_t event_hs_wait_q;
u8 cmd_complete;
bool is_suspended;
};
......@@ -89,6 +90,7 @@ struct btmrvl_private {
#define MRVL_VENDOR_PKT 0xFE
/* Vendor specific Bluetooth commands */
#define BT_CMD_PSCAN_WIN_REPORT_ENABLE 0xFC03
#define BT_CMD_AUTO_SLEEP_MODE 0xFC23
#define BT_CMD_HOST_SLEEP_CONFIG 0xFC59
#define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A
......@@ -143,6 +145,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
int btmrvl_enable_ps(struct btmrvl_private *priv);
int btmrvl_prepare_command(struct btmrvl_private *priv);
......
......@@ -114,6 +114,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode)
adapter->ps_state = PS_SLEEP;
wake_up_interruptible(&adapter->event_hs_wait_q);
BT_DBG("HS ACTIVATED!");
} else {
BT_DBG("HS Enable failed");
......@@ -214,6 +215,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
}
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
{
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
int ret;
if (!card->support_pscan_win_report)
return 0;
ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
&subcmd, 1);
if (ret)
BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);
return ret;
}
EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
{
int ret;
......@@ -253,11 +271,31 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
int btmrvl_enable_hs(struct btmrvl_private *priv)
{
struct btmrvl_adapter *adapter = priv->adapter;
int ret;
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
if (ret)
if (ret) {
BT_ERR("Host sleep enable command failed\n");
return ret;
}
ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
adapter->hs_state,
msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED));
if (ret < 0) {
BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
ret, adapter->hs_state, adapter->ps_state,
adapter->wakeup_tries);
} else if (!ret) {
BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
adapter->ps_state, adapter->wakeup_tries);
ret = -ETIMEDOUT;
} else {
BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
adapter->ps_state, adapter->wakeup_tries);
ret = 0;
}
return ret;
}
......@@ -358,6 +396,7 @@ static void btmrvl_init_adapter(struct btmrvl_private *priv)
}
init_waitqueue_head(&priv->adapter->cmd_wait_q);
init_waitqueue_head(&priv->adapter->event_hs_wait_q);
}
static void btmrvl_free_adapter(struct btmrvl_private *priv)
......@@ -489,6 +528,8 @@ static int btmrvl_setup(struct hci_dev *hdev)
btmrvl_cal_data_dt(priv);
btmrvl_pscan_window_reporting(priv, 0x01);
priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv);
......@@ -666,6 +707,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
hdev = priv->btmrvl_dev.hcidev;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
wake_up_interruptible(&priv->adapter->event_hs_wait_q);
kthread_stop(priv->main_thread.task);
......
......@@ -108,6 +108,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
.reg = &btmrvl_reg_8688,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 64,
};
......@@ -115,6 +116,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
.reg = &btmrvl_reg_87xx,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
};
......@@ -122,6 +124,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
.reg = &btmrvl_reg_87xx,
.support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
};
......@@ -129,6 +132,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin",
.reg = &btmrvl_reg_88xx,
.support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
};
......@@ -1067,6 +1071,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
card->firmware = data->firmware;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
card->support_pscan_win_report = data->support_pscan_win_report;
}
if (btmrvl_sdio_register_dev(card) < 0) {
......
......@@ -89,6 +89,7 @@ struct btmrvl_sdio_card {
const char *helper;
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
bool support_pscan_win_report;
u16 sd_blksz_fw_dl;
u8 rx_unit;
struct btmrvl_private *priv;
......@@ -98,6 +99,7 @@ struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
const bool support_pscan_win_report;
u16 sd_blksz_fw_dl;
};
......
......@@ -30,9 +30,6 @@
#define VERSION "0.6"
static bool ignore_dga;
static bool ignore_csr;
static bool ignore_sniffer;
static bool disable_scofix;
static bool force_scofix;
......@@ -49,7 +46,8 @@ static struct usb_driver btusb_driver;
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100
#define BTUSB_BCM_PATCHRAM 0x200
#define BTUSB_INTEL_BOOT 0x200
#define BTUSB_BCM_PATCHRAM 0x400
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
......@@ -121,6 +119,10 @@ static const struct usb_device_id btusb_table[] = {
/* IMC Networks - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
/* Intel Bluetooth USB Bootloader (RAM module) */
{ USB_DEVICE(0x8087, 0x0a5a),
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
{ } /* Terminating entry */
};
......@@ -162,7 +164,6 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
......@@ -176,6 +177,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
......@@ -229,10 +231,12 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
/* CSR BlueCore Bluetooth Sniffer */
{ USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
{ USB_DEVICE(0x0a12, 0x0002),
.driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Frontline ComProbe Bluetooth Sniffer */
{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
{ USB_DEVICE(0x16d3, 0x0002),
.driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Intel Bluetooth device */
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
......@@ -1183,6 +1187,51 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
return 0;
}
#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}})
static int btusb_check_bdaddr_intel(struct hci_dev *hdev)
{
struct sk_buff *skb;
struct hci_rp_read_bd_addr *rp;
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
BT_ERR("%s reading Intel device address failed (%ld)",
hdev->name, PTR_ERR(skb));
return PTR_ERR(skb);
}
if (skb->len != sizeof(*rp)) {
BT_ERR("%s Intel device address length mismatch", hdev->name);
kfree_skb(skb);
return -EIO;
}
rp = (struct hci_rp_read_bd_addr *) skb->data;
if (rp->status) {
BT_ERR("%s Intel device address result failed (%02x)",
hdev->name, rp->status);
kfree_skb(skb);
return -bt_to_errno(rp->status);
}
/* For some Intel based controllers, the default Bluetooth device
* address 00:03:19:9E:8B:00 can be found. These controllers are
* fully operational, but have the danger of duplicate addresses
* and that in turn can cause problems with Bluetooth operation.
*/
if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
BT_ERR("%s found Intel default device address (%pMR)",
hdev->name, &rp->bdaddr);
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
}
kfree_skb(skb);
return 0;
}
static int btusb_setup_intel(struct hci_dev *hdev)
{
struct sk_buff *skb;
......@@ -1255,6 +1304,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_INFO("%s: Intel device is already patched. patch num: %02x",
hdev->name, ver->fw_patch_num);
kfree_skb(skb);
btusb_check_bdaddr_intel(hdev);
return 0;
}
......@@ -1267,6 +1317,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
fw = btusb_setup_intel_get_fw(hdev, ver);
if (!fw) {
kfree_skb(skb);
btusb_check_bdaddr_intel(hdev);
return 0;
}
fw_ptr = fw->data;
......@@ -1346,6 +1397,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
hdev->name);
btusb_check_bdaddr_intel(hdev);
return 0;
exit_mfg_disable:
......@@ -1360,6 +1412,8 @@ static int btusb_setup_intel(struct hci_dev *hdev)
kfree_skb(skb);
BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
btusb_check_bdaddr_intel(hdev);
return 0;
exit_mfg_deactivate:
......@@ -1380,9 +1434,29 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
hdev->name);
btusb_check_bdaddr_intel(hdev);
return 0;
}
static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
{
struct sk_buff *skb;
long ret;
skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
ret = PTR_ERR(skb);
BT_ERR("%s: changing Intel 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)
{
struct btusb_data *data = hci_get_drvdata(hdev);
......@@ -1396,6 +1470,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
u16 opcode;
struct sk_buff *skb;
struct hci_rp_read_local_version *ver;
struct hci_rp_read_bd_addr *bda;
long ret;
snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
......@@ -1405,8 +1480,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
ret = request_firmware(&fw, fw_name, &hdev->dev);
if (ret < 0) {
BT_INFO("%s: BCM: patch %s not found", hdev->name,
fw_name);
BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
return 0;
}
......@@ -1525,12 +1599,67 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
ver->lmp_ver, ver->lmp_subver);
kfree_skb(skb);
/* Read BD Address */
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
ret = PTR_ERR(skb);
BT_ERR("%s: HCI_OP_READ_BD_ADDR failed (%ld)",
hdev->name, ret);
goto done;
}
if (skb->len != sizeof(*bda)) {
BT_ERR("%s: HCI_OP_READ_BD_ADDR event length mismatch",
hdev->name);
kfree_skb(skb);
ret = -EIO;
goto done;
}
bda = (struct hci_rp_read_bd_addr *) skb->data;
if (bda->status) {
BT_ERR("%s: HCI_OP_READ_BD_ADDR error status (%02x)",
hdev->name, bda->status);
kfree_skb(skb);
ret = -bt_to_errno(bda->status);
goto done;
}
/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
* with no configured address.
*/
if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
BT_INFO("%s: BCM: using default device address (%pMR)",
hdev->name, &bda->bdaddr);
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
}
kfree_skb(skb);
done:
release_firmware(fw);
return ret;
}
static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr)
{
struct sk_buff *skb;
long ret;
skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
ret = PTR_ERR(skb);
BT_ERR("%s: BCM: Change address command failed (%ld)",
hdev->name, ret);
return ret;
}
kfree_skb(skb);
return 0;
}
static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
......@@ -1555,15 +1684,6 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info == BTUSB_IGNORE)
return -ENODEV;
if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
return -ENODEV;
if (ignore_csr && id->driver_info & BTUSB_CSR)
return -ENODEV;
if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
return -ENODEV;
if (id->driver_info & BTUSB_ATH3012) {
struct usb_device *udev = interface_to_usbdev(intf);
......@@ -1636,11 +1756,18 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
if (id->driver_info & BTUSB_BCM_PATCHRAM)
if (id->driver_info & BTUSB_BCM_PATCHRAM) {
hdev->setup = btusb_setup_bcm_patchram;
hdev->set_bdaddr = btusb_set_bdaddr_bcm;
}
if (id->driver_info & BTUSB_INTEL)
if (id->driver_info & BTUSB_INTEL) {
hdev->setup = btusb_setup_intel;
hdev->set_bdaddr = btusb_set_bdaddr_intel;
}
if (id->driver_info & BTUSB_INTEL_BOOT)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
......@@ -1680,8 +1807,18 @@ static int btusb_probe(struct usb_interface *intf,
/* New sniffer firmware has crippled HCI interface */
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
}
data->isoc = NULL;
if (id->driver_info & BTUSB_INTEL_BOOT) {
/* A bug in the bootloader causes that interrupt interface is
* only enabled after receiving SetInterface(0, AltSetting=0).
*/
err = usb_set_interface(data->udev, 0, 0);
if (err < 0) {
BT_ERR("failed to set interface 0, alt 0 %d", err);
hci_free_dev(hdev);
return err;
}
}
if (data->isoc) {
......@@ -1846,15 +1983,6 @@ static struct usb_driver btusb_driver = {
module_usb_driver(btusb_driver);
module_param(ignore_dga, bool, 0644);
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
module_param(ignore_csr, bool, 0644);
MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
module_param(ignore_sniffer, bool, 0644);
MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
module_param(disable_scofix, bool, 0644);
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
......
......@@ -355,10 +355,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
{
struct h5 *h5 = hu->priv;
h5_complete_rx_pkt(hu);
h5_reset_rx(h5);
return 0;
}
......@@ -373,7 +370,6 @@ static int h5_rx_payload(struct hci_uart *hu, unsigned char c)
h5->rx_pending = 2;
} else {
h5_complete_rx_pkt(hu);
h5_reset_rx(h5);
}
return 0;
......@@ -406,6 +402,7 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
BT_ERR("Non-link packet received in non-active state");
h5_reset_rx(h5);
return 0;
}
h5->rx_func = h5_rx_payload;
......
......@@ -40,7 +40,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#define VERSION "1.4"
#define VERSION "1.5"
static bool amp;
......@@ -95,10 +95,21 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}
static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
static int vhci_create_device(struct vhci_data *data, __u8 opcode)
{
struct hci_dev *hdev;
struct sk_buff *skb;
__u8 dev_type;
/* bits 0-1 are dev_type (BR/EDR or AMP) */
dev_type = opcode & 0x03;
if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
return -EINVAL;
/* bits 2-5 are reserved (must be zero) */
if (opcode & 0x3c)
return -EINVAL;
skb = bt_skb_alloc(4, GFP_KERNEL);
if (!skb)
......@@ -121,6 +132,14 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
hdev->flush = vhci_flush;
hdev->send = vhci_send_frame;
/* bit 6 is for external configuration */
if (opcode & 0x40)
set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
/* bit 7 is for raw device */
if (opcode & 0x80)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
......@@ -132,7 +151,7 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
*skb_put(skb, 1) = 0xff;
*skb_put(skb, 1) = dev_type;
*skb_put(skb, 1) = opcode;
put_unaligned_le16(hdev->id, skb_put(skb, 2));
skb_queue_tail(&data->readq, skb);
......@@ -146,7 +165,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
{
size_t len = iov_length(iov, count);
struct sk_buff *skb;
__u8 pkt_type, dev_type;
__u8 pkt_type, opcode;
unsigned long i;
int ret;
......@@ -190,7 +209,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
cancel_delayed_work_sync(&data->open_timeout);
dev_type = *((__u8 *) skb->data);
opcode = *((__u8 *) skb->data);
skb_pull(skb, 1);
if (skb->len > 0) {
......@@ -200,10 +219,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
kfree_skb(skb);
if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
return -EINVAL;
ret = vhci_create_device(data, dev_type);
ret = vhci_create_device(data, opcode);
break;
default:
......
......@@ -795,7 +795,11 @@ int ath10k_core_start(struct ath10k *ar)
if (status)
goto err_htc_stop;
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
else
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
INIT_LIST_HEAD(&ar->arvifs);
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
......
......@@ -312,7 +312,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
int msdu_len, msdu_chaining = 0;
struct sk_buff *msdu;
struct htt_rx_desc *rx_desc;
bool corrupted = false;
lockdep_assert_held(&htt->rx_ring.lock);
......@@ -439,9 +438,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
RX_MSDU_END_INFO0_LAST_MSDU;
if (msdu_chaining && !last_msdu)
corrupted = true;
if (last_msdu) {
msdu->next = NULL;
break;
......@@ -456,20 +452,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
if (*head_msdu == NULL)
msdu_chaining = -1;
/*
* Apparently FW sometimes reports weird chained MSDU sequences with
* more than one rx descriptor. This seems like a bug but needs more
* analyzing. For the time being fix it by dropping such sequences to
* avoid blowing up the host system.
*/
if (corrupted) {
ath10k_warn("failed to pop chained msdus, dropping\n");
ath10k_htt_rx_free_msdu_chain(*head_msdu);
*head_msdu = NULL;
*tail_msdu = NULL;
msdu_chaining = -EINVAL;
}
/*
* Don't refill the ring yet.
*
......
......@@ -1183,8 +1183,6 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
bus->bus_priv.usb = bus_pub;
dev_set_drvdata(dev, bus);
bus->ops = &brcmf_usb_bus_ops;
bus->chip = bus_pub->devid;
bus->chiprev = bus_pub->chiprev;
bus->proto_type = BRCMF_PROTO_BCDC;
bus->always_use_fws_queue = true;
......@@ -1193,6 +1191,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
if (ret)
goto fail;
}
bus->chip = bus_pub->devid;
bus->chiprev = bus_pub->chiprev;
/* request firmware here */
brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
brcmf_usb_probe_phase2);
......
......@@ -185,6 +185,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
tx_info_aggr->bss_type = tx_info_src->bss_type;
tx_info_aggr->bss_num = tx_info_src->bss_num;
......
......@@ -188,6 +188,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = pkt_len;
......
......@@ -462,6 +462,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
if (skb) {
rx_info = MWIFIEX_SKB_RXCB(skb);
memset(rx_info, 0, sizeof(*rx_info));
rx_info->bss_num = priv->bss_num;
rx_info->bss_type = priv->bss_type;
}
......
......@@ -644,6 +644,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = skb->len;
......
......@@ -150,6 +150,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
return -1;
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
......
......@@ -604,6 +604,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
......@@ -757,6 +758,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
skb->priority = MWIFIEX_PRIO_VI;
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
......
......@@ -55,6 +55,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
return -1;
}
memset(rx_info, 0, sizeof(*rx_info));
rx_info->bss_num = priv->bss_num;
rx_info->bss_type = priv->bss_type;
......
......@@ -174,6 +174,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
......
......@@ -231,9 +231,12 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
*/
static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
{
__le32 reg;
__le32 *reg;
u32 fw_mode;
reg = kmalloc(sizeof(*reg), GFP_KERNEL);
if (reg == NULL)
return -ENOMEM;
/* cannot use rt2x00usb_register_read here as it uses different
* mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
* magic value USB_MODE_AUTORUN (0x11) to the device, thus the
......@@ -241,8 +244,9 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
*/
rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
&reg, sizeof(reg), REGISTER_TIMEOUT_FIRMWARE);
fw_mode = le32_to_cpu(reg);
reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE);
fw_mode = le32_to_cpu(*reg);
kfree(reg);
if ((fw_mode & 0x00000003) == 2)
return 1;
......@@ -261,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
int status;
u32 offset;
u32 length;
int retval;
/*
* Check which section of the firmware we need.
......@@ -278,7 +283,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
if (rt2800usb_autorun_detect(rt2x00dev)) {
retval = rt2800usb_autorun_detect(rt2x00dev);
if (retval < 0)
return retval;
if (retval) {
rt2x00_info(rt2x00dev,
"Firmware loading not required - NIC in AutoRun mode\n");
} else {
......@@ -763,7 +771,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
*/
static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
{
if (rt2800usb_autorun_detect(rt2x00dev))
int retval;
retval = rt2800usb_autorun_detect(rt2x00dev);
if (retval < 0)
return retval;
if (retval)
return 1;
return rt2800_efuse_detect(rt2x00dev);
}
......@@ -772,7 +785,10 @@ static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
{
int retval;
if (rt2800usb_efuse_detect(rt2x00dev))
retval = rt2800usb_efuse_detect(rt2x00dev);
if (retval < 0)
return retval;
if (retval)
retval = rt2800_read_eeprom_efuse(rt2x00dev);
else
retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
......
......@@ -260,7 +260,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct l2cap_ctrl {
unsigned int sframe:1,
__u8 sframe:1,
poll:1,
final:1,
fcs:1,
......
......@@ -81,10 +81,54 @@
/* HCI device quirks */
enum {
/* When this quirk is set, the HCI Reset command is send when
* closing the transport instead of when opening it.
*
* This quirk must be set before hci_register_dev is called.
*/
HCI_QUIRK_RESET_ON_CLOSE,
/* When this quirk is set, the device is turned into a raw-only
* device and it will stay in unconfigured state.
*
* This quirk must be set before hci_register_dev is called.
*/
HCI_QUIRK_RAW_DEVICE,
/* When this quirk is set, the buffer sizes reported by
* HCI Read Buffer Size command are corrected if invalid.
*
* This quirk must be set before hci_register_dev is called.
*/
HCI_QUIRK_FIXUP_BUFFER_SIZE,
/* When this quirk is set, then no stored link key handling
* is performed. This is mainly due to the fact that the
* HCI Delete Stored Link Key command is advertised, but
* not supported.
*
* This quirk must be set before hci_register_dev is called.
*/
HCI_QUIRK_BROKEN_STORED_LINK_KEY,
/* When this quirk is set, an external configuration step
* is required and will be indicated with the controller
* configuation.
*
* This quirk can be set before hci_register_dev is called or
* during the hdev->setup vendor callback.
*/
HCI_QUIRK_EXTERNAL_CONFIG,
/* When this quirk is set, the public Bluetooth address
* initially reported by HCI Read BD Address command
* is considered invalid. Controller configuration is
* required before this device can be used.
*
* This quirk can be set before hci_register_dev is called or
* during the hdev->setup vendor callback.
*/
HCI_QUIRK_INVALID_BDADDR,
};
/* HCI device flags */
......@@ -104,24 +148,34 @@ enum {
HCI_RESET,
};
/* BR/EDR and/or LE controller flags: the flags defined here should represent
* states configured via debugfs for debugging and testing purposes only.
*/
enum {
HCI_DUT_MODE,
HCI_FORCE_SC,
HCI_FORCE_STATIC_ADDR,
};
/*
* BR/EDR and/or LE controller flags: the flags defined here should represent
* states from the controller.
*/
enum {
HCI_SETUP,
HCI_CONFIG,
HCI_AUTO_OFF,
HCI_RFKILLED,
HCI_MGMT,
HCI_PAIRABLE,
HCI_SERVICE_CACHE,
HCI_DEBUG_KEYS,
HCI_DUT_MODE,
HCI_FORCE_SC,
HCI_FORCE_STATIC_ADDR,
HCI_KEEP_DEBUG_KEYS,
HCI_USE_DEBUG_KEYS,
HCI_UNREGISTER,
HCI_UNCONFIGURED,
HCI_USER_CHANNEL,
HCI_EXT_CONFIGURED,
HCI_LE_ADV,
HCI_LE_SCAN,
HCI_SSP_ENABLED,
HCI_SC_ENABLED,
......@@ -139,7 +193,6 @@ enum {
HCI_PERIODIC_INQ,
HCI_FAST_CONNECTABLE,
HCI_BREDR_ENABLED,
HCI_6LOWPAN_ENABLED,
HCI_LE_SCAN_INTERRUPTED,
};
......@@ -147,7 +200,7 @@ enum {
* or the HCI device is closed.
*/
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
BIT(HCI_FAST_CONNECTABLE))
BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV))
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
......@@ -185,6 +238,7 @@ enum {
#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
#define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
#define HCI_LE_AUTOCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
......@@ -301,6 +355,10 @@ enum {
#define LMP_HOST_LE_BREDR 0x04
#define LMP_HOST_SC 0x08
/* LE features */
#define HCI_LE_CONN_PARAM_REQ_PROC 0x02
#define HCI_LE_PING 0x10
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
#define HCI_CM_HOLD 0x0001
......@@ -347,17 +405,9 @@ enum {
#define HCI_LK_CHANGED_COMBINATION 0x06
#define HCI_LK_UNAUTH_COMBINATION_P256 0x07
#define HCI_LK_AUTH_COMBINATION_P256 0x08
/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
#define HCI_SMP_STK 0x80
#define HCI_SMP_STK_SLAVE 0x81
#define HCI_SMP_LTK 0x82
#define HCI_SMP_LTK_SLAVE 0x83
/* Long Term Key types */
#define HCI_LTK_UNAUTH 0x00
#define HCI_LTK_AUTH 0x01
/* ---- HCI Error Codes ---- */
#define HCI_ERROR_UNKNOWN_CONN_ID 0x02
#define HCI_ERROR_AUTH_FAILURE 0x05
#define HCI_ERROR_MEMORY_EXCEEDED 0x07
#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
......@@ -367,6 +417,7 @@ enum {
#define HCI_ERROR_REMOTE_POWER_OFF 0x15
#define HCI_ERROR_LOCAL_HOST_TERM 0x16
#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18
#define HCI_ERROR_INVALID_LL_PARAMS 0x1E
#define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c
/* Flow control modes */
......@@ -536,6 +587,11 @@ struct hci_cp_read_remote_version {
__le16 handle;
} __packed;
#define HCI_OP_READ_CLOCK_OFFSET 0x041f
struct hci_cp_read_clock_offset {
__le16 handle;
} __packed;
#define HCI_OP_SETUP_SYNC_CONN 0x0428
struct hci_cp_setup_sync_conn {
__le16 handle;
......@@ -1085,6 +1141,18 @@ struct hci_rp_read_rssi {
__s8 rssi;
} __packed;
#define HCI_OP_READ_CLOCK 0x1407
struct hci_cp_read_clock {
__le16 handle;
__u8 which;
} __packed;
struct hci_rp_read_clock {
__u8 status;
__le16 handle;
__le32 clock;
__le16 accuracy;
} __packed;
#define HCI_OP_READ_LOCAL_AMP_INFO 0x1409
struct hci_rp_read_local_amp_info {
__u8 status;
......@@ -1291,6 +1359,23 @@ struct hci_rp_le_read_supported_states {
__u8 le_states[8];
} __packed;
#define HCI_OP_LE_CONN_PARAM_REQ_REPLY 0x2020
struct hci_cp_le_conn_param_req_reply {
__le16 handle;
__le16 interval_min;
__le16 interval_max;
__le16 latency;
__le16 timeout;
__le16 min_ce_len;
__le16 max_ce_len;
} __packed;
#define HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY 0x2021
struct hci_cp_le_conn_param_req_neg_reply {
__le16 handle;
__u8 reason;
} __packed;
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
......@@ -1670,6 +1755,15 @@ struct hci_ev_le_conn_complete {
__u8 clk_accurancy;
} __packed;
#define HCI_EV_LE_CONN_UPDATE_COMPLETE 0x03
struct hci_ev_le_conn_update_complete {
__u8 status;
__le16 handle;
__le16 interval;
__le16 latency;
__le16 supervision_timeout;
} __packed;
#define HCI_EV_LE_LTK_REQ 0x05
struct hci_ev_le_ltk_req {
__le16 handle;
......@@ -1677,6 +1771,15 @@ struct hci_ev_le_ltk_req {
__le16 ediv;
} __packed;
#define HCI_EV_LE_REMOTE_CONN_PARAM_REQ 0x06
struct hci_ev_le_remote_conn_param_req {
__le16 handle;
__le16 interval_min;
__le16 interval_max;
__le16 latency;
__le16 timeout;
} __packed;
/* Advertising report event types */
#define LE_ADV_IND 0x00
#define LE_ADV_DIRECT_IND 0x01
......
......@@ -71,6 +71,7 @@ struct discovery_state {
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
s8 last_adv_rssi;
u32 last_adv_flags;
u8 last_adv_data[HCI_MAX_AD_LENGTH];
u8 last_adv_data_len;
};
......@@ -170,6 +171,8 @@ struct hci_dev {
__u8 bus;
__u8 dev_type;
bdaddr_t bdaddr;
bdaddr_t setup_addr;
bdaddr_t public_addr;
bdaddr_t random_addr;
bdaddr_t static_addr;
__u8 adv_addr_type;
......@@ -203,10 +206,13 @@ struct hci_dev {
__u16 le_scan_window;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
__u16 le_conn_latency;
__u16 le_supv_timeout;
__u16 discov_interleaved_timeout;
__u16 conn_info_min_age;
__u16 conn_info_max_age;
__u8 ssp_debug_mode;
__u32 clock;
__u16 devid_source;
__u16 devid_vendor;
......@@ -273,7 +279,7 @@ struct hci_dev {
struct delayed_work service_cache;
struct timer_list cmd_timer;
struct delayed_work cmd_timer;
struct work_struct rx_work;
struct work_struct cmd_work;
......@@ -299,6 +305,7 @@ struct hci_dev {
struct list_head mgmt_pending;
struct list_head blacklist;
struct list_head whitelist;
struct list_head uuids;
struct list_head link_keys;
struct list_head long_term_keys;
......@@ -307,6 +314,7 @@ struct hci_dev {
struct list_head le_white_list;
struct list_head le_conn_params;
struct list_head pend_le_conns;
struct list_head pend_le_reports;
struct hci_dev_stats stat;
......@@ -318,6 +326,7 @@ struct hci_dev {
struct rfkill *rfkill;
unsigned long dbg_flags;
unsigned long dev_flags;
struct delayed_work le_scan_disable;
......@@ -339,6 +348,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);
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
};
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
......@@ -366,7 +376,6 @@ struct hci_conn {
__u8 features[HCI_MAX_PAGES][8];
__u16 pkt_type;
__u16 link_policy;
__u32 link_mode;
__u8 key_type;
__u8 auth_type;
__u8 sec_level;
......@@ -377,20 +386,26 @@ struct hci_conn {
__u32 passkey_notify;
__u8 passkey_entered;
__u16 disc_timeout;
__u16 conn_timeout;
__u16 setting;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
__u16 le_conn_interval;
__u16 le_conn_latency;
__u16 le_supv_timeout;
__s8 rssi;
__s8 tx_power;
__s8 max_tx_power;
unsigned long flags;
__u32 clock;
__u16 clock_accuracy;
unsigned long conn_info_timestamp;
__u8 remote_cap;
__u8 remote_auth;
__u8 remote_id;
bool flush_key;
unsigned int sent;
......@@ -407,7 +422,6 @@ struct hci_conn {
struct hci_dev *hdev;
void *l2cap_data;
void *sco_data;
void *smp_conn;
struct amp_mgr *amp_mgr;
struct hci_conn *link;
......@@ -428,15 +442,19 @@ struct hci_chan {
struct hci_conn_params {
struct list_head list;
struct list_head action;
bdaddr_t addr;
u8 addr_type;
u16 conn_min_interval;
u16 conn_max_interval;
u16 conn_latency;
u16 supervision_timeout;
enum {
HCI_AUTO_CONN_DISABLED,
HCI_AUTO_CONN_REPORT,
HCI_AUTO_CONN_ALWAYS,
HCI_AUTO_CONN_LINK_LOSS,
} auto_connect;
......@@ -501,8 +519,8 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
int state);
void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
struct inquiry_entry *ie);
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known, bool *ssp);
u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known);
void hci_inquiry_cache_flush(struct hci_dev *hdev);
/* ----- HCI Connections ----- */
......@@ -520,7 +538,13 @@ enum {
HCI_CONN_AES_CCM,
HCI_CONN_POWER_SAVE,
HCI_CONN_REMOTE_OOB,
HCI_CONN_6LOWPAN,
HCI_CONN_FLUSH_KEY,
HCI_CONN_MASTER,
HCI_CONN_ENCRYPT,
HCI_CONN_AUTH,
HCI_CONN_SECURE,
HCI_CONN_FIPS,
HCI_CONN_STK_ENCRYPT,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
......@@ -681,7 +705,8 @@ void hci_chan_list_flush(struct hci_conn *conn);
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, u8 auth_type);
u8 dst_type, u8 sec_level, u16 conn_timeout,
bool master);
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,
......@@ -825,30 +850,25 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg);
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type);
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
bdaddr_t *bdaddr, u8 type);
void hci_white_list_clear(struct hci_dev *hdev);
int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
void hci_bdaddr_list_clear(struct list_head *list);
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
u8 auto_connect, u16 conn_min_interval,
u16 conn_max_interval);
struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
u8 auto_connect);
void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_conn_params_clear(struct hci_dev *hdev);
void hci_conn_params_clear_all(struct hci_dev *hdev);
void hci_conn_params_clear_disabled(struct hci_dev *hdev);
struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
void hci_pend_le_conns_clear(struct hci_dev *hdev);
struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
bdaddr_t *addr,
u8 addr_type);
void hci_update_background_scan(struct hci_dev *hdev);
......@@ -856,8 +876,9 @@ void hci_uuids_clear(struct hci_dev *hdev);
void hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
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);
struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
......@@ -1021,7 +1042,7 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
l2cap_security_cfm(conn, status, encrypt);
if (conn->security_cfm_cb)
......@@ -1062,7 +1083,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
read_lock(&hci_cb_list_lock);
list_for_each_entry(cb, &hci_cb_list, list) {
......@@ -1147,7 +1168,7 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
{
if (addr_type != 0x01)
if (addr_type != ADDR_LE_DEV_RANDOM)
return false;
if ((bdaddr->b[5] & 0xc0) == 0x40)
......@@ -1156,6 +1177,18 @@ static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
return false;
}
static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type)
{
if (addr_type == ADDR_LE_DEV_PUBLIC)
return true;
/* Check for Random Static address type */
if ((addr->b[5] & 0xc0) == 0xc0)
return true;
return false;
}
static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 addr_type)
{
......@@ -1165,6 +1198,27 @@ static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
return hci_find_irk_by_rpa(hdev, bdaddr);
}
static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
u16 to_multiplier)
{
u16 max_latency;
if (min > max || min < 6 || max > 3200)
return -EINVAL;
if (to_multiplier < 10 || to_multiplier > 3200)
return -EINVAL;
if (max >= to_multiplier * 8)
return -EINVAL;
max_latency = (to_multiplier * 8 / max) - 1;
if (latency > 499 || latency > max_latency)
return -EINVAL;
return 0;
}
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
......@@ -1227,6 +1281,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_BREDR_INQUIRY_LEN 0x08
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_new_settings(struct hci_dev *hdev);
void mgmt_index_added(struct hci_dev *hdev);
void mgmt_index_removed(struct hci_dev *hdev);
void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
......@@ -1234,7 +1289,6 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered);
void mgmt_discoverable_timeout(struct hci_dev *hdev);
void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
void mgmt_advertising(struct hci_dev *hdev, u8 advertising);
void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
bool persistent);
......@@ -1281,18 +1335,18 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
u8 *randomizer192, u8 *hash256,
u8 *randomizer256, u8 status);
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp,
u8 scan_rsp_len);
u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len);
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
bool persistent);
void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 bdaddr_type, u8 store_hint, u16 min_interval,
u16 max_interval, u16 latency, u16 timeout);
void mgmt_reenable_advertising(struct hci_dev *hdev);
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
......@@ -1324,8 +1378,8 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier);
u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
u16 to_multiplier);
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
__u8 ltk[16]);
......
......@@ -137,7 +137,6 @@ struct l2cap_conninfo {
#define L2CAP_FC_L2CAP 0x02
#define L2CAP_FC_CONNLESS 0x04
#define L2CAP_FC_A2MP 0x08
#define L2CAP_FC_6LOWPAN 0x3e /* reserved and temporary value */
/* L2CAP Control Field bit masks */
#define L2CAP_CTRL_SAR 0xC000
......@@ -579,7 +578,7 @@ struct l2cap_chan {
struct list_head global_l;
void *data;
struct l2cap_ops *ops;
const struct l2cap_ops *ops;
struct mutex lock;
};
......@@ -600,7 +599,12 @@ struct l2cap_ops {
void (*set_shutdown) (struct l2cap_chan *chan);
long (*get_sndtimeo) (struct l2cap_chan *chan);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb);
int (*memcpy_fromiovec) (struct l2cap_chan *chan,
unsigned char *kdata,
struct iovec *iov,
int len);
};
struct l2cap_conn {
......@@ -856,6 +860,31 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan)
return 0;
}
static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
unsigned char *kdata,
struct iovec *iov,
int len)
{
/* Following is safe since for compiler definitions of kvec and
* iovec are identical, yielding the same in-core layout and alignment
*/
struct kvec *vec = (struct kvec *)iov;
while (len > 0) {
if (vec->iov_len) {
int copy = min_t(unsigned int, len, vec->iov_len);
memcpy(kdata, vec->iov_base, copy);
len -= copy;
kdata += copy;
vec->iov_base += copy;
vec->iov_len -= copy;
}
vec++;
}
return 0;
}
extern bool disable_ertm;
int l2cap_init_sockets(void);
......@@ -872,8 +901,7 @@ struct l2cap_chan *l2cap_chan_create(void);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
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,
u32 priority);
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);
void l2cap_chan_set_defaults(struct l2cap_chan *chan);
......
......@@ -97,6 +97,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_SECURE_CONN 0x00000800
#define MGMT_SETTING_DEBUG_KEYS 0x00001000
#define MGMT_SETTING_PRIVACY 0x00002000
#define MGMT_SETTING_CONFIGURATION 0x00004000
#define MGMT_OP_READ_INFO 0x0004
#define MGMT_READ_INFO_SIZE 0
......@@ -424,6 +425,76 @@ struct mgmt_rp_get_conn_info {
__s8 max_tx_power;
} __packed;
#define MGMT_OP_GET_CLOCK_INFO 0x0032
struct mgmt_cp_get_clock_info {
struct mgmt_addr_info addr;
} __packed;
#define MGMT_GET_CLOCK_INFO_SIZE MGMT_ADDR_INFO_SIZE
struct mgmt_rp_get_clock_info {
struct mgmt_addr_info addr;
__le32 local_clock;
__le32 piconet_clock;
__le16 accuracy;
} __packed;
#define MGMT_OP_ADD_DEVICE 0x0033
struct mgmt_cp_add_device {
struct mgmt_addr_info addr;
__u8 action;
} __packed;
#define MGMT_ADD_DEVICE_SIZE (MGMT_ADDR_INFO_SIZE + 1)
#define MGMT_OP_REMOVE_DEVICE 0x0034
struct mgmt_cp_remove_device {
struct mgmt_addr_info addr;
} __packed;
#define MGMT_REMOVE_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
struct mgmt_conn_param {
struct mgmt_addr_info addr;
__le16 min_interval;
__le16 max_interval;
__le16 latency;
__le16 timeout;
} __packed;
#define MGMT_OP_LOAD_CONN_PARAM 0x0035
struct mgmt_cp_load_conn_param {
__le16 param_count;
struct mgmt_conn_param params[0];
} __packed;
#define MGMT_LOAD_CONN_PARAM_SIZE 2
#define MGMT_OP_READ_UNCONF_INDEX_LIST 0x0036
#define MGMT_READ_UNCONF_INDEX_LIST_SIZE 0
struct mgmt_rp_read_unconf_index_list {
__le16 num_controllers;
__le16 index[0];
} __packed;
#define MGMT_OPTION_EXTERNAL_CONFIG 0x00000001
#define MGMT_OPTION_PUBLIC_ADDRESS 0x00000002
#define MGMT_OP_READ_CONFIG_INFO 0x0037
#define MGMT_READ_CONFIG_INFO_SIZE 0
struct mgmt_rp_read_config_info {
__le16 manufacturer;
__le32 supported_options;
__le32 missing_options;
} __packed;
#define MGMT_OP_SET_EXTERNAL_CONFIG 0x0038
struct mgmt_cp_set_external_config {
__u8 config;
} __packed;
#define MGMT_SET_EXTERNAL_CONFIG_SIZE 1
#define MGMT_OP_SET_PUBLIC_ADDRESS 0x0039
struct mgmt_cp_set_public_address {
bdaddr_t bdaddr;
} __packed;
#define MGMT_SET_PUBLIC_ADDRESS_SIZE 6
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
......@@ -522,6 +593,7 @@ struct mgmt_ev_auth_failed {
#define MGMT_DEV_FOUND_CONFIRM_NAME 0x01
#define MGMT_DEV_FOUND_LEGACY_PAIRING 0x02
#define MGMT_DEV_FOUND_NOT_CONNECTABLE 0x04
#define MGMT_EV_DEVICE_FOUND 0x0012
struct mgmt_ev_device_found {
......@@ -578,3 +650,30 @@ struct mgmt_ev_new_csrk {
__u8 store_hint;
struct mgmt_csrk_info key;
} __packed;
#define MGMT_EV_DEVICE_ADDED 0x001a
struct mgmt_ev_device_added {
struct mgmt_addr_info addr;
__u8 action;
} __packed;
#define MGMT_EV_DEVICE_REMOVED 0x001b
struct mgmt_ev_device_removed {
struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_NEW_CONN_PARAM 0x001c
struct mgmt_ev_new_conn_param {
struct mgmt_addr_info addr;
__u8 store_hint;
__le16 min_interval;
__le16 max_interval;
__le16 latency;
__le16 timeout;
} __packed;
#define MGMT_EV_UNCONF_INDEX_ADDED 0x001d
#define MGMT_EV_UNCONF_INDEX_REMOVED 0x001e
#define MGMT_EV_NEW_CONFIG_OPTIONS 0x001f
/*
Copyright (c) 2013 Intel Corp.
Copyright (c) 2013-2014 Intel Corp.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 and
......@@ -14,6 +14,8 @@
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/debugfs.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
......@@ -25,16 +27,20 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include "6lowpan.h"
#include <net/6lowpan.h> /* for the compression support */
#define VERSION "0.1"
static struct dentry *lowpan_psm_debugfs;
static struct dentry *lowpan_control_debugfs;
#define IFACE_NAME_TEMPLATE "bt%d"
#define EUI64_ADDR_LEN 8
struct skb_cb {
struct in6_addr addr;
struct l2cap_conn *conn;
struct l2cap_chan *chan;
int status;
};
#define lowpan_cb(skb) ((struct skb_cb *)((skb)->cb))
......@@ -48,9 +54,19 @@ struct skb_cb {
static LIST_HEAD(bt_6lowpan_devices);
static DEFINE_RWLOCK(devices_lock);
/* If psm is set to 0 (default value), then 6lowpan is disabled.
* Other values are used to indicate a Protocol Service Multiplexer
* value for 6lowpan.
*/
static u16 psm_6lowpan;
/* We are listening incoming connections via this channel
*/
static struct l2cap_chan *listen_chan;
struct lowpan_peer {
struct list_head list;
struct l2cap_conn *conn;
struct l2cap_chan *chan;
/* peer addresses in various formats */
unsigned char eui64_addr[EUI64_ADDR_LEN];
......@@ -84,6 +100,8 @@ static inline bool peer_del(struct lowpan_dev *dev, struct lowpan_peer *peer)
{
list_del(&peer->list);
module_put(THIS_MODULE);
if (atomic_dec_and_test(&dev->peer_count)) {
BT_DBG("last peer");
return true;
......@@ -101,13 +119,26 @@ static inline struct lowpan_peer *peer_lookup_ba(struct lowpan_dev *dev,
ba, type);
list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
BT_DBG("addr %pMR type %d",
&peer->conn->hcon->dst, peer->conn->hcon->dst_type);
BT_DBG("dst addr %pMR dst type %d",
&peer->chan->dst, peer->chan->dst_type);
if (bacmp(&peer->conn->hcon->dst, ba))
if (bacmp(&peer->chan->dst, ba))
continue;
if (type == peer->conn->hcon->dst_type)
if (type == peer->chan->dst_type)
return peer;
}
return NULL;
}
static inline struct lowpan_peer *peer_lookup_chan(struct lowpan_dev *dev,
struct l2cap_chan *chan)
{
struct lowpan_peer *peer, *tmp;
list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
if (peer->chan == chan)
return peer;
}
......@@ -120,7 +151,7 @@ static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev,
struct lowpan_peer *peer, *tmp;
list_for_each_entry_safe(peer, tmp, &dev->peers, list) {
if (peer->conn == conn)
if (peer->chan->conn == conn)
return peer;
}
......@@ -176,16 +207,16 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
return -ENOMEM;
ret = netif_rx(skb_cp);
if (ret < 0) {
BT_DBG("receive skb %d", ret);
if (ret < 0)
return NET_RX_DROP;
}
return ret;
}
static int process_data(struct sk_buff *skb, struct net_device *netdev,
struct l2cap_conn *conn)
struct l2cap_chan *chan)
{
const u8 *saddr, *daddr;
u8 iphc0, iphc1;
......@@ -196,7 +227,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
dev = lowpan_dev(netdev);
read_lock_irqsave(&devices_lock, flags);
peer = peer_lookup_conn(dev, conn);
peer = peer_lookup_chan(dev, chan);
read_unlock_irqrestore(&devices_lock, flags);
if (!peer)
goto drop;
......@@ -225,7 +256,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
}
static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
struct l2cap_conn *conn)
struct l2cap_chan *chan)
{
struct sk_buff *local_skb;
int ret;
......@@ -269,7 +300,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
if (!local_skb)
goto drop;
ret = process_data(local_skb, dev, conn);
ret = process_data(local_skb, dev, chan);
if (ret != NET_RX_SUCCESS)
goto drop;
......@@ -286,147 +317,39 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
return NET_RX_SUCCESS;
drop:
dev->stats.rx_dropped++;
kfree_skb(skb);
return NET_RX_DROP;
}
/* Packet from BT LE device */
int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{
struct lowpan_dev *dev;
struct lowpan_peer *peer;
int err;
peer = lookup_peer(conn);
peer = lookup_peer(chan->conn);
if (!peer)
return -ENOENT;
dev = lookup_dev(conn);
dev = lookup_dev(chan->conn);
if (!dev || !dev->netdev)
return -ENOENT;
err = recv_pkt(skb, dev->netdev, conn);
err = recv_pkt(skb, dev->netdev, chan);
if (err) {
BT_DBG("recv pkt %d", err);
return err;
}
static inline int skbuff_copy(void *msg, int len, int count, int mtu,
struct sk_buff *skb, struct net_device *dev)
{
struct sk_buff **frag;
int sent = 0;
memcpy(skb_put(skb, count), msg, count);
sent += count;
msg += count;
len -= count;
dev->stats.tx_bytes += count;
dev->stats.tx_packets++;
raw_dump_table(__func__, "Sending", skb->data, skb->len);
/* Continuation fragments (no L2CAP header) */
frag = &skb_shinfo(skb)->frag_list;
while (len > 0) {
struct sk_buff *tmp;
count = min_t(unsigned int, mtu, len);
tmp = bt_skb_alloc(count, GFP_ATOMIC);
if (!tmp)
return -ENOMEM;
*frag = tmp;
memcpy(skb_put(*frag, count), msg, count);
raw_dump_table(__func__, "Sending fragment",
(*frag)->data, count);
(*frag)->priority = skb->priority;
sent += count;
msg += count;
len -= count;
skb->len += (*frag)->len;
skb->data_len += (*frag)->len;
frag = &(*frag)->next;
dev->stats.tx_bytes += count;
dev->stats.tx_packets++;
err = -EAGAIN;
}
return sent;
}
static struct sk_buff *create_pdu(struct l2cap_conn *conn, void *msg,
size_t len, u32 priority,
struct net_device *dev)
{
struct sk_buff *skb;
int err, count;
struct l2cap_hdr *lh;
/* FIXME: This mtu check should be not needed and atm is only used for
* testing purposes
*/
if (conn->mtu > (L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE))
conn->mtu = L2CAP_LE_MIN_MTU + L2CAP_HDR_SIZE;
count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
BT_DBG("conn %p len %zu mtu %d count %d", conn, len, conn->mtu, count);
skb = bt_skb_alloc(count + L2CAP_HDR_SIZE, GFP_ATOMIC);
if (!skb)
return ERR_PTR(-ENOMEM);
skb->priority = priority;
lh = (struct l2cap_hdr *)skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(L2CAP_FC_6LOWPAN);
lh->len = cpu_to_le16(len);
err = skbuff_copy(msg, len, count, conn->mtu, skb, dev);
if (unlikely(err < 0)) {
kfree_skb(skb);
BT_DBG("skbuff copy %d failed", err);
return ERR_PTR(err);
}
return skb;
}
static int conn_send(struct l2cap_conn *conn,
void *msg, size_t len, u32 priority,
struct net_device *dev)
{
struct sk_buff *skb;
skb = create_pdu(conn, msg, len, priority, dev);
if (IS_ERR(skb))
return -EINVAL;
BT_DBG("conn %p skb %p len %d priority %u", conn, skb, skb->len,
skb->priority);
hci_send_acl(conn->hchan, skb, ACL_START);
return 0;
return err;
}
static u8 get_addr_type_from_eui64(u8 byte)
{
/* Is universal(0) or local(1) bit, */
if (byte & 0x02)
return ADDR_LE_DEV_RANDOM;
return ADDR_LE_DEV_PUBLIC;
/* Is universal(0) or local(1) bit */
return ((byte & 0x02) ? BDADDR_LE_RANDOM : BDADDR_LE_PUBLIC);
}
static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
......@@ -475,7 +398,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
if (ipv6_addr_is_multicast(&hdr->daddr)) {
memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
sizeof(struct in6_addr));
lowpan_cb(skb)->conn = NULL;
lowpan_cb(skb)->chan = NULL;
} else {
unsigned long flags;
......@@ -484,9 +407,8 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
*/
convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
BT_DBG("dest addr %pMR type %s IP %pI6c", &addr,
addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
&hdr->daddr);
BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
addr_type, &hdr->daddr);
read_lock_irqsave(&devices_lock, flags);
peer = peer_lookup_ba(dev, &addr, addr_type);
......@@ -501,7 +423,7 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
memcpy(&lowpan_cb(skb)->addr, &hdr->daddr,
sizeof(struct in6_addr));
lowpan_cb(skb)->conn = peer->conn;
lowpan_cb(skb)->chan = peer->chan;
}
saddr = dev->netdev->dev_addr;
......@@ -510,14 +432,42 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
}
/* Packet to BT LE device */
static int send_pkt(struct l2cap_conn *conn, const void *saddr,
const void *daddr, struct sk_buff *skb,
static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
struct net_device *netdev)
{
raw_dump_table(__func__, "raw skb data dump before fragmentation",
skb->data, skb->len);
struct msghdr msg;
struct kvec iv;
int err;
/* Remember the skb so that we can send EAGAIN to the caller if
* we run out of credits.
*/
chan->data = skb;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = (struct iovec *) &iv;
msg.msg_iovlen = 1;
iv.iov_base = skb->data;
iv.iov_len = skb->len;
err = l2cap_chan_send(chan, &msg, skb->len);
if (err > 0) {
netdev->stats.tx_bytes += err;
netdev->stats.tx_packets++;
return 0;
}
if (!err)
err = lowpan_cb(skb)->status;
if (err < 0) {
if (err == -EAGAIN)
netdev->stats.tx_dropped++;
else
netdev->stats.tx_errors++;
}
return conn_send(conn, skb->data, skb->len, 0, netdev);
return err;
}
static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
......@@ -540,8 +490,7 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
list_for_each_entry_safe(pentry, ptmp, &dev->peers, list) {
local_skb = skb_clone(skb, GFP_ATOMIC);
send_pkt(pentry->conn, netdev->dev_addr,
pentry->eui64_addr, local_skb, netdev);
send_pkt(pentry->chan, local_skb, netdev);
kfree_skb(local_skb);
}
......@@ -553,7 +502,6 @@ static void send_mcast_pkt(struct sk_buff *skb, struct net_device *netdev)
static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
{
int err = 0;
unsigned char *eui64_addr;
struct lowpan_dev *dev;
struct lowpan_peer *peer;
bdaddr_t addr;
......@@ -568,21 +516,20 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned long flags;
convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
dev = lowpan_dev(netdev);
read_lock_irqsave(&devices_lock, flags);
peer = peer_lookup_ba(dev, &addr, addr_type);
read_unlock_irqrestore(&devices_lock, flags);
BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p",
netdev->name, &addr,
addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p",
netdev->name, &addr, addr_type,
&lowpan_cb(skb)->addr, peer);
if (peer && peer->conn)
err = send_pkt(peer->conn, netdev->dev_addr,
eui64_addr, skb, netdev);
if (peer && peer->chan)
err = send_pkt(peer->chan, skb, netdev);
else
err = -ENOENT;
}
dev_kfree_skb(skb);
......@@ -634,7 +581,7 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
eui[7] = addr[0];
/* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
if (addr_type == ADDR_LE_DEV_PUBLIC)
if (addr_type == BDADDR_LE_PUBLIC)
eui[0] &= ~0x02;
else
eui[0] |= 0x02;
......@@ -660,6 +607,17 @@ static void ifup(struct net_device *netdev)
rtnl_unlock();
}
static void ifdown(struct net_device *netdev)
{
int err;
rtnl_lock();
err = dev_close(netdev);
if (err < 0)
BT_INFO("iface %s cannot be closed (%d)", netdev->name, err);
rtnl_unlock();
}
static void do_notify_peers(struct work_struct *work)
{
struct lowpan_dev *dev = container_of(work, struct lowpan_dev,
......@@ -673,26 +631,64 @@ static bool is_bt_6lowpan(struct hci_conn *hcon)
if (hcon->type != LE_LINK)
return false;
return test_bit(HCI_CONN_6LOWPAN, &hcon->flags);
if (!psm_6lowpan)
return false;
return true;
}
static struct l2cap_chan *chan_create(void)
{
struct l2cap_chan *chan;
chan = l2cap_chan_create();
if (!chan)
return NULL;
l2cap_chan_set_defaults(chan);
chan->chan_type = L2CAP_CHAN_CONN_ORIENTED;
chan->mode = L2CAP_MODE_LE_FLOWCTL;
chan->omtu = 65535;
chan->imtu = chan->omtu;
return chan;
}
static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev)
static struct l2cap_chan *chan_open(struct l2cap_chan *pchan)
{
struct l2cap_chan *chan;
chan = chan_create();
if (!chan)
return NULL;
chan->remote_mps = chan->omtu;
chan->mps = chan->omtu;
chan->state = BT_CONNECTED;
return chan;
}
static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
struct lowpan_dev *dev)
{
struct lowpan_peer *peer;
unsigned long flags;
peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
if (!peer)
return -ENOMEM;
return NULL;
peer->conn = conn;
peer->chan = chan;
memset(&peer->peer_addr, 0, sizeof(struct in6_addr));
/* RFC 2464 ch. 5 */
peer->peer_addr.s6_addr[0] = 0xFE;
peer->peer_addr.s6_addr[1] = 0x80;
set_addr((u8 *)&peer->peer_addr.s6_addr + 8, conn->hcon->dst.b,
conn->hcon->dst_type);
set_addr((u8 *)&peer->peer_addr.s6_addr + 8, chan->dst.b,
chan->dst_type);
memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
EUI64_ADDR_LEN);
......@@ -706,40 +702,24 @@ static int add_peer_conn(struct l2cap_conn *conn, struct lowpan_dev *dev)
INIT_DELAYED_WORK(&dev->notify_peers, do_notify_peers);
schedule_delayed_work(&dev->notify_peers, msecs_to_jiffies(100));
return 0;
return peer->chan;
}
/* This gets called when BT LE 6LoWPAN device is connected. We then
* create network device that acts as a proxy between BT LE device
* and kernel network stack.
*/
int bt_6lowpan_add_conn(struct l2cap_conn *conn)
static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
{
struct lowpan_peer *peer = NULL;
struct lowpan_dev *dev;
struct net_device *netdev;
int err = 0;
unsigned long flags;
if (!is_bt_6lowpan(conn->hcon))
return 0;
peer = lookup_peer(conn);
if (peer)
return -EEXIST;
dev = lookup_dev(conn);
if (dev)
return add_peer_conn(conn, dev);
netdev = alloc_netdev(sizeof(*dev), IFACE_NAME_TEMPLATE, netdev_setup);
netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
netdev_setup);
if (!netdev)
return -ENOMEM;
set_dev_addr(netdev, &conn->hcon->src, conn->hcon->src_type);
set_dev_addr(netdev, &chan->src, chan->src_type);
netdev->netdev_ops = &netdev_ops;
SET_NETDEV_DEV(netdev, &conn->hcon->dev);
SET_NETDEV_DEV(netdev, &chan->conn->hcon->dev);
SET_NETDEV_DEVTYPE(netdev, &bt_type);
err = register_netdev(netdev);
......@@ -749,28 +729,61 @@ int bt_6lowpan_add_conn(struct l2cap_conn *conn)
goto out;
}
BT_DBG("ifindex %d peer bdaddr %pMR my addr %pMR",
netdev->ifindex, &conn->hcon->dst, &conn->hcon->src);
BT_DBG("ifindex %d peer bdaddr %pMR type %d my addr %pMR type %d",
netdev->ifindex, &chan->dst, chan->dst_type,
&chan->src, chan->src_type);
set_bit(__LINK_STATE_PRESENT, &netdev->state);
dev = netdev_priv(netdev);
dev->netdev = netdev;
dev->hdev = conn->hcon->hdev;
INIT_LIST_HEAD(&dev->peers);
*dev = netdev_priv(netdev);
(*dev)->netdev = netdev;
(*dev)->hdev = chan->conn->hcon->hdev;
INIT_LIST_HEAD(&(*dev)->peers);
write_lock_irqsave(&devices_lock, flags);
INIT_LIST_HEAD(&dev->list);
list_add(&dev->list, &bt_6lowpan_devices);
INIT_LIST_HEAD(&(*dev)->list);
list_add(&(*dev)->list, &bt_6lowpan_devices);
write_unlock_irqrestore(&devices_lock, flags);
ifup(netdev);
return add_peer_conn(conn, dev);
return 0;
out:
return err;
}
static inline void chan_ready_cb(struct l2cap_chan *chan)
{
struct lowpan_dev *dev;
dev = lookup_dev(chan->conn);
BT_DBG("chan %p conn %p dev %p", chan, chan->conn, dev);
if (!dev) {
if (setup_netdev(chan, &dev) < 0) {
l2cap_chan_del(chan, -ENOENT);
return;
}
}
if (!try_module_get(THIS_MODULE))
return;
add_peer_chan(chan, dev);
ifup(dev->netdev);
}
static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *chan)
{
struct l2cap_chan *pchan;
pchan = chan_open(chan);
pchan->ops = chan->ops;
BT_DBG("chan %p pchan %p", chan, pchan);
return pchan;
}
static void delete_netdev(struct work_struct *work)
{
struct lowpan_dev *entry = container_of(work, struct lowpan_dev,
......@@ -781,26 +794,43 @@ static void delete_netdev(struct work_struct *work)
/* The entry pointer is deleted in device_event() */
}
int bt_6lowpan_del_conn(struct l2cap_conn *conn)
static void chan_close_cb(struct l2cap_chan *chan)
{
struct lowpan_dev *entry, *tmp;
struct lowpan_dev *dev = NULL;
struct lowpan_peer *peer;
int err = -ENOENT;
unsigned long flags;
bool last = false;
bool last = false, removed = true;
if (!conn || !is_bt_6lowpan(conn->hcon))
return 0;
BT_DBG("chan %p conn %p", chan, chan->conn);
if (chan->conn && chan->conn->hcon) {
if (!is_bt_6lowpan(chan->conn->hcon))
return;
/* If conn is set, then the netdev is also there and we should
* not remove it.
*/
removed = false;
}
write_lock_irqsave(&devices_lock, flags);
list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
dev = lowpan_dev(entry->netdev);
peer = peer_lookup_conn(dev, conn);
peer = peer_lookup_chan(dev, chan);
if (peer) {
last = peer_del(dev, peer);
err = 0;
BT_DBG("dev %p removing %speer %p", dev,
last ? "last " : "1 ", peer);
BT_DBG("chan %p orig refcnt %d", chan,
atomic_read(&chan->kref.refcount));
l2cap_chan_put(chan);
kfree(peer);
break;
}
}
......@@ -810,18 +840,402 @@ int bt_6lowpan_del_conn(struct l2cap_conn *conn)
cancel_delayed_work_sync(&dev->notify_peers);
/* bt_6lowpan_del_conn() is called with hci dev lock held which
* means that we must delete the netdevice in worker thread.
*/
ifdown(dev->netdev);
if (!removed) {
INIT_WORK(&entry->delete_netdev, delete_netdev);
schedule_work(&entry->delete_netdev);
}
} else {
write_unlock_irqrestore(&devices_lock, flags);
}
return;
}
static void chan_state_change_cb(struct l2cap_chan *chan, int state, int err)
{
BT_DBG("chan %p conn %p state %s err %d", chan, chan->conn,
state_to_string(state), err);
}
static struct sk_buff *chan_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb)
{
/* Note that we must allocate using GFP_ATOMIC here as
* this function is called originally from netdev hard xmit
* function in atomic context.
*/
return bt_skb_alloc(hdr_len + len, GFP_ATOMIC);
}
static void chan_suspend_cb(struct l2cap_chan *chan)
{
struct sk_buff *skb = chan->data;
BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
lowpan_cb(skb)->status = -EAGAIN;
}
static void chan_resume_cb(struct l2cap_chan *chan)
{
struct sk_buff *skb = chan->data;
BT_DBG("chan %p conn %p skb %p", chan, chan->conn, skb);
lowpan_cb(skb)->status = 0;
}
static long chan_get_sndtimeo_cb(struct l2cap_chan *chan)
{
return msecs_to_jiffies(1000);
}
static const struct l2cap_ops bt_6lowpan_chan_ops = {
.name = "L2CAP 6LoWPAN channel",
.new_connection = chan_new_conn_cb,
.recv = chan_recv_cb,
.close = chan_close_cb,
.state_change = chan_state_change_cb,
.ready = chan_ready_cb,
.resume = chan_resume_cb,
.suspend = chan_suspend_cb,
.get_sndtimeo = chan_get_sndtimeo_cb,
.alloc_skb = chan_alloc_skb_cb,
.memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
.teardown = l2cap_chan_no_teardown,
.defer = l2cap_chan_no_defer,
.set_shutdown = l2cap_chan_no_set_shutdown,
};
static inline __u8 bdaddr_type(__u8 type)
{
if (type == ADDR_LE_DEV_PUBLIC)
return BDADDR_LE_PUBLIC;
else
return BDADDR_LE_RANDOM;
}
static struct l2cap_chan *chan_get(void)
{
struct l2cap_chan *pchan;
pchan = chan_create();
if (!pchan)
return NULL;
pchan->ops = &bt_6lowpan_chan_ops;
return pchan;
}
static int bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type)
{
struct l2cap_chan *pchan;
int err;
pchan = chan_get();
if (!pchan)
return -EINVAL;
err = l2cap_chan_connect(pchan, cpu_to_le16(psm_6lowpan), 0,
addr, dst_type);
BT_DBG("chan %p err %d", pchan, err);
if (err < 0)
l2cap_chan_put(pchan);
return err;
}
static int bt_6lowpan_disconnect(struct l2cap_conn *conn, u8 dst_type)
{
struct lowpan_peer *peer;
BT_DBG("conn %p dst type %d", conn, dst_type);
peer = lookup_peer(conn);
if (!peer)
return -ENOENT;
BT_DBG("peer %p chan %p", peer, peer->chan);
l2cap_chan_close(peer->chan, ENOENT);
return 0;
}
static struct l2cap_chan *bt_6lowpan_listen(void)
{
bdaddr_t *addr = BDADDR_ANY;
struct l2cap_chan *pchan;
int err;
if (psm_6lowpan == 0)
return NULL;
pchan = chan_get();
if (!pchan)
return NULL;
pchan->state = BT_LISTEN;
pchan->src_type = BDADDR_LE_PUBLIC;
BT_DBG("psm 0x%04x chan %p src type %d", psm_6lowpan, pchan,
pchan->src_type);
err = l2cap_add_psm(pchan, addr, cpu_to_le16(psm_6lowpan));
if (err) {
l2cap_chan_put(pchan);
BT_ERR("psm cannot be added err %d", err);
return NULL;
}
return pchan;
}
static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
struct l2cap_conn **conn)
{
struct hci_conn *hcon;
struct hci_dev *hdev;
bdaddr_t *src = BDADDR_ANY;
int n;
n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
&addr->b[5], &addr->b[4], &addr->b[3],
&addr->b[2], &addr->b[1], &addr->b[0],
addr_type);
if (n < 7)
return -EINVAL;
hdev = hci_get_route(addr, src);
if (!hdev)
return -ENOENT;
hci_dev_lock(hdev);
hcon = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
hci_dev_unlock(hdev);
if (!hcon)
return -ENOENT;
*conn = (struct l2cap_conn *)hcon->l2cap_data;
BT_DBG("conn %p dst %pMR type %d", *conn, &hcon->dst, hcon->dst_type);
return 0;
}
static void disconnect_all_peers(void)
{
struct lowpan_dev *entry, *tmp_dev;
struct lowpan_peer *peer, *tmp_peer, *new_peer;
struct list_head peers;
unsigned long flags;
INIT_LIST_HEAD(&peers);
/* We make a separate list of peers as the close_cb() will
* modify the device peers list so it is better not to mess
* with the same list at the same time.
*/
read_lock_irqsave(&devices_lock, flags);
list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) {
list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list) {
new_peer = kmalloc(sizeof(*new_peer), GFP_ATOMIC);
if (!new_peer)
break;
new_peer->chan = peer->chan;
INIT_LIST_HEAD(&new_peer->list);
list_add(&new_peer->list, &peers);
}
}
read_unlock_irqrestore(&devices_lock, flags);
list_for_each_entry_safe(peer, tmp_peer, &peers, list) {
l2cap_chan_close(peer->chan, ENOENT);
kfree(peer);
}
}
static int lowpan_psm_set(void *data, u64 val)
{
u16 psm;
psm = val;
if (psm == 0 || psm_6lowpan != psm)
/* Disconnect existing connections if 6lowpan is
* disabled (psm = 0), or if psm changes.
*/
disconnect_all_peers();
psm_6lowpan = psm;
if (listen_chan) {
l2cap_chan_close(listen_chan, 0);
l2cap_chan_put(listen_chan);
}
listen_chan = bt_6lowpan_listen();
return 0;
}
static int lowpan_psm_get(void *data, u64 *val)
{
*val = psm_6lowpan;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(lowpan_psm_fops, lowpan_psm_get,
lowpan_psm_set, "%llu\n");
static ssize_t lowpan_control_write(struct file *fp,
const char __user *user_buffer,
size_t count,
loff_t *position)
{
char buf[32];
size_t buf_size = min(count, sizeof(buf) - 1);
int ret;
bdaddr_t addr;
u8 addr_type;
struct l2cap_conn *conn = NULL;
if (copy_from_user(buf, user_buffer, buf_size))
return -EFAULT;
buf[buf_size] = '\0';
if (memcmp(buf, "connect ", 8) == 0) {
ret = get_l2cap_conn(&buf[8], &addr, &addr_type, &conn);
if (ret == -EINVAL)
return ret;
if (listen_chan) {
l2cap_chan_close(listen_chan, 0);
l2cap_chan_put(listen_chan);
listen_chan = NULL;
}
if (conn) {
struct lowpan_peer *peer;
if (!is_bt_6lowpan(conn->hcon))
return -EINVAL;
peer = lookup_peer(conn);
if (peer) {
BT_DBG("6LoWPAN connection already exists");
return -EALREADY;
}
BT_DBG("conn %p dst %pMR type %d user %d", conn,
&conn->hcon->dst, conn->hcon->dst_type,
addr_type);
}
ret = bt_6lowpan_connect(&addr, addr_type);
if (ret < 0)
return ret;
return count;
}
if (memcmp(buf, "disconnect ", 11) == 0) {
ret = get_l2cap_conn(&buf[11], &addr, &addr_type, &conn);
if (ret < 0)
return ret;
ret = bt_6lowpan_disconnect(conn, addr_type);
if (ret < 0)
return ret;
return count;
}
return count;
}
static int lowpan_control_show(struct seq_file *f, void *ptr)
{
struct lowpan_dev *entry, *tmp_dev;
struct lowpan_peer *peer, *tmp_peer;
unsigned long flags;
read_lock_irqsave(&devices_lock, flags);
list_for_each_entry_safe(entry, tmp_dev, &bt_6lowpan_devices, list) {
list_for_each_entry_safe(peer, tmp_peer, &entry->peers, list)
seq_printf(f, "%pMR (type %u)\n",
&peer->chan->dst, peer->chan->dst_type);
}
read_unlock_irqrestore(&devices_lock, flags);
return 0;
}
static int lowpan_control_open(struct inode *inode, struct file *file)
{
return single_open(file, lowpan_control_show, inode->i_private);
}
static const struct file_operations lowpan_control_fops = {
.open = lowpan_control_open,
.read = seq_read,
.write = lowpan_control_write,
.llseek = seq_lseek,
.release = single_release,
};
static void disconnect_devices(void)
{
struct lowpan_dev *entry, *tmp, *new_dev;
struct list_head devices;
unsigned long flags;
INIT_LIST_HEAD(&devices);
/* We make a separate list of devices because the unregister_netdev()
* will call device_event() which will also want to modify the same
* devices list.
*/
read_lock_irqsave(&devices_lock, flags);
list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices, list) {
new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC);
if (!new_dev)
break;
new_dev->netdev = entry->netdev;
INIT_LIST_HEAD(&new_dev->list);
list_add(&new_dev->list, &devices);
}
read_unlock_irqrestore(&devices_lock, flags);
list_for_each_entry_safe(entry, tmp, &devices, list) {
ifdown(entry->netdev);
BT_DBG("Unregistering netdev %s %p",
entry->netdev->name, entry->netdev);
unregister_netdev(entry->netdev);
kfree(entry);
}
}
static int device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
......@@ -838,6 +1252,8 @@ static int device_event(struct notifier_block *unused,
list_for_each_entry_safe(entry, tmp, &bt_6lowpan_devices,
list) {
if (entry->netdev == netdev) {
BT_DBG("Unregistered netdev %s %p",
netdev->name, netdev);
list_del(&entry->list);
kfree(entry);
break;
......@@ -854,12 +1270,37 @@ static struct notifier_block bt_6lowpan_dev_notifier = {
.notifier_call = device_event,
};
int bt_6lowpan_init(void)
static int __init bt_6lowpan_init(void)
{
lowpan_psm_debugfs = debugfs_create_file("6lowpan_psm", 0644,
bt_debugfs, NULL,
&lowpan_psm_fops);
lowpan_control_debugfs = debugfs_create_file("6lowpan_control", 0644,
bt_debugfs, NULL,
&lowpan_control_fops);
return register_netdevice_notifier(&bt_6lowpan_dev_notifier);
}
void bt_6lowpan_cleanup(void)
static void __exit bt_6lowpan_exit(void)
{
debugfs_remove(lowpan_psm_debugfs);
debugfs_remove(lowpan_control_debugfs);
if (listen_chan) {
l2cap_chan_close(listen_chan, 0);
l2cap_chan_put(listen_chan);
}
disconnect_devices();
unregister_netdevice_notifier(&bt_6lowpan_dev_notifier);
}
module_init(bt_6lowpan_init);
module_exit(bt_6lowpan_exit);
MODULE_AUTHOR("Jukka Rissanen <jukka.rissanen@linux.intel.com>");
MODULE_DESCRIPTION("Bluetooth 6LoWPAN");
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
/*
Copyright (c) 2013 Intel Corp.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 and
only version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef __6LOWPAN_H
#define __6LOWPAN_H
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/bluetooth/l2cap.h>
#if IS_ENABLED(CONFIG_BT_6LOWPAN)
int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
int bt_6lowpan_add_conn(struct l2cap_conn *conn);
int bt_6lowpan_del_conn(struct l2cap_conn *conn);
int bt_6lowpan_init(void);
void bt_6lowpan_cleanup(void);
#else
static int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
return -EOPNOTSUPP;
}
static int bt_6lowpan_add_conn(struct l2cap_conn *conn)
{
return -EOPNOTSUPP;
}
int bt_6lowpan_del_conn(struct l2cap_conn *conn)
{
return -EOPNOTSUPP;
}
static int bt_6lowpan_init(void)
{
return -EOPNOTSUPP;
}
static void bt_6lowpan_cleanup(void) { }
#endif
#endif /* __6LOWPAN_H */
......@@ -6,7 +6,6 @@ menuconfig BT
tristate "Bluetooth subsystem support"
depends on NET && !S390
depends on RFKILL || !RFKILL
select 6LOWPAN_IPHC if BT_6LOWPAN
select CRC16
select CRYPTO
select CRYPTO_BLKCIPHER
......@@ -41,10 +40,11 @@ menuconfig BT
more information, see <http://www.bluez.org/>.
config BT_6LOWPAN
bool "Bluetooth 6LoWPAN support"
tristate "Bluetooth 6LoWPAN support"
depends on BT && IPV6
select 6LOWPAN_IPHC if BT_6LOWPAN
help
IPv6 compression over Bluetooth.
IPv6 compression over Bluetooth Low Energy.
source "net/bluetooth/rfcomm/Kconfig"
......
......@@ -7,10 +7,12 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/
obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/
obj-$(CONFIG_BT_HIDP) += hidp/
obj-$(CONFIG_BT_6LOWPAN) += bluetooth_6lowpan.o
bluetooth_6lowpan-y := 6lowpan.o
bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
a2mp.o amp.o
bluetooth-$(CONFIG_BT_6LOWPAN) += 6lowpan.o
subdir-ccflags-y += -D__CHECK_ENDIAN__
......@@ -63,7 +63,7 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
msg.msg_iov = (struct iovec *) &iv;
msg.msg_iovlen = 1;
l2cap_chan_send(chan, &msg, total_len, 0);
l2cap_chan_send(chan, &msg, total_len);
kfree(cmd);
}
......@@ -693,18 +693,19 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state,
}
static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb)
{
struct sk_buff *skb;
skb = bt_skb_alloc(len, GFP_KERNEL);
skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL);
if (!skb)
return ERR_PTR(-ENOMEM);
return skb;
}
static struct l2cap_ops a2mp_chan_ops = {
static const struct l2cap_ops a2mp_chan_ops = {
.name = "L2CAP A2MP channel",
.recv = a2mp_chan_recv_cb,
.close = a2mp_chan_close_cb,
......@@ -719,6 +720,7 @@ static struct l2cap_ops a2mp_chan_ops = {
.resume = l2cap_chan_no_resume,
.set_shutdown = l2cap_chan_no_set_shutdown,
.get_sndtimeo = l2cap_chan_no_get_sndtimeo,
.memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec,
};
static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
......
......@@ -639,7 +639,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
return 0;
}
static struct seq_operations bt_seq_ops = {
static const struct seq_operations bt_seq_ops = {
.start = bt_seq_start,
.next = bt_seq_next,
.stop = bt_seq_stop,
......
......@@ -67,7 +67,7 @@ static void hci_acl_create_connection(struct hci_conn *conn)
conn->state = BT_CONNECT;
conn->out = true;
conn->link_mode = HCI_LM_MASTER;
set_bit(HCI_CONN_MASTER, &conn->flags);
conn->attempt++;
......@@ -136,7 +136,7 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason)
hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
}
static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
static void hci_amp_disconn(struct hci_conn *conn)
{
struct hci_cp_disconn_phy_link cp;
......@@ -145,7 +145,7 @@ static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
conn->state = BT_DISCONN;
cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
cp.reason = reason;
cp.reason = hci_proto_disconn_ind(conn);
hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
sizeof(cp), &cp);
}
......@@ -213,14 +213,26 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
return true;
}
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier)
u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
u16 to_multiplier)
{
struct hci_cp_le_conn_update cp;
struct hci_dev *hdev = conn->hdev;
struct hci_conn_params *params;
struct hci_cp_le_conn_update cp;
memset(&cp, 0, sizeof(cp));
hci_dev_lock(hdev);
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
if (params) {
params->conn_min_interval = min;
params->conn_max_interval = max;
params->conn_latency = latency;
params->supervision_timeout = to_multiplier;
}
hci_dev_unlock(hdev);
memset(&cp, 0, sizeof(cp));
cp.handle = cpu_to_le16(conn->handle);
cp.conn_interval_min = cpu_to_le16(min);
cp.conn_interval_max = cpu_to_le16(max);
......@@ -230,6 +242,11 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
cp.max_ce_len = cpu_to_le16(0x0000);
hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
if (params)
return 0x01;
return 0x00;
}
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
......@@ -271,28 +288,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status)
}
}
static void hci_conn_disconnect(struct hci_conn *conn)
{
__u8 reason = hci_proto_disconn_ind(conn);
switch (conn->type) {
case AMP_LINK:
hci_amp_disconn(conn, reason);
break;
default:
hci_disconnect(conn, reason);
break;
}
}
static void hci_conn_timeout(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn,
disc_work.work);
int refcnt = atomic_read(&conn->refcnt);
BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
if (atomic_read(&conn->refcnt))
WARN_ON(refcnt < 0);
/* FIXME: It was observed that in pairing failed scenario, refcnt
* drops below 0. Probably this is because l2cap_conn_del calls
* l2cap_chan_del for each channel, and inside l2cap_chan_del conn is
* dropped. After that loop hci_chan_del is called which also drops
* conn. For now make sure that ACL is alive if refcnt is higher then 0,
* otherwise drop it.
*/
if (refcnt > 0)
return;
switch (conn->state) {
......@@ -309,7 +322,31 @@ static void hci_conn_timeout(struct work_struct *work)
break;
case BT_CONFIG:
case BT_CONNECTED:
hci_conn_disconnect(conn);
if (conn->type == AMP_LINK) {
hci_amp_disconn(conn);
} else {
__u8 reason = hci_proto_disconn_ind(conn);
/* When we are master of an established connection
* and it enters the disconnect timeout, then go
* ahead and try to read the current clock offset.
*
* Processing of the result is done within the
* event handling and hci_clock_offset_evt function.
*/
if (conn->type == ACL_LINK &&
test_bit(HCI_CONN_MASTER, &conn->flags)) {
struct hci_dev *hdev = conn->hdev;
struct hci_cp_read_clock_offset cp;
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET,
sizeof(cp), &cp);
}
hci_disconnect(conn, reason);
}
break;
default:
conn->state = BT_CLOSED;
......@@ -326,9 +363,6 @@ static void hci_conn_idle(struct work_struct *work)
BT_DBG("hcon %p mode %d", conn, conn->mode);
if (test_bit(HCI_RAW, &hdev->flags))
return;
if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn))
return;
......@@ -519,7 +553,6 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
list_for_each_entry(d, &hci_dev_list, list) {
if (!test_bit(HCI_UP, &d->flags) ||
test_bit(HCI_RAW, &d->flags) ||
test_bit(HCI_USER_CHANNEL, &d->dev_flags) ||
d->dev_type != HCI_BREDR)
continue;
......@@ -617,7 +650,8 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
cp.own_address_type = own_addr_type;
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
cp.supervision_timeout = cpu_to_le16(0x002a);
cp.conn_latency = cpu_to_le16(conn->le_conn_latency);
cp.supervision_timeout = cpu_to_le16(conn->le_supv_timeout);
cp.min_ce_len = cpu_to_le16(0x0000);
cp.max_ce_len = cpu_to_le16(0x0000);
......@@ -634,15 +668,12 @@ static void hci_req_directed_advertising(struct hci_request *req,
u8 own_addr_type;
u8 enable;
enable = 0x00;
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
/* Clear the HCI_ADVERTISING bit temporarily so that the
/* Clear the HCI_LE_ADV bit temporarily so that the
* hci_update_random_address knows that it's safe to go ahead
* 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_ADVERTISING, &hdev->dev_flags);
clear_bit(HCI_LE_ADV, &hdev->dev_flags);
/* Set require_privacy to false so that the remote device has a
* chance of identifying us.
......@@ -666,7 +697,8 @@ 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, u8 auth_type)
u8 dst_type, u8 sec_level, u16 conn_timeout,
bool master)
{
struct hci_conn_params *params;
struct hci_conn *conn;
......@@ -686,7 +718,6 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
if (conn) {
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
goto done;
}
......@@ -723,25 +754,52 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
conn->dst_type = dst_type;
conn->sec_level = BT_SECURITY_LOW;
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
conn->conn_timeout = conn_timeout;
hci_req_init(&req, hdev);
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
/* Disable advertising if we're active. For master role
* connections most controllers will refuse to connect if
* advertising is enabled, and for slave role connections we
* anyway have to disable it in order to start directed
* advertising.
*/
if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
u8 enable = 0x00;
hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
&enable);
}
/* If requested to connect as slave use directed advertising */
if (!master) {
/* If we're active scanning most controllers are unable
* to initiate advertising. Simply reject the attempt.
*/
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
hdev->le_scan_type == LE_SCAN_ACTIVE) {
skb_queue_purge(&req.cmd_q);
hci_conn_del(conn);
return ERR_PTR(-EBUSY);
}
hci_req_directed_advertising(&req, conn);
goto create_conn;
}
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
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;
conn->le_conn_max_interval = params->conn_max_interval;
conn->le_conn_latency = params->conn_latency;
conn->le_supv_timeout = params->supervision_timeout;
} else {
conn->le_conn_min_interval = hdev->le_conn_min_interval;
conn->le_conn_max_interval = hdev->le_conn_max_interval;
conn->le_conn_latency = hdev->le_conn_latency;
conn->le_supv_timeout = hdev->le_supv_timeout;
}
/* If controller is scanning, we stop it since some controllers are
......@@ -855,7 +913,8 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
return 0;
}
if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
if (hci_conn_ssp_enabled(conn) &&
!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
return 0;
return 1;
......@@ -871,7 +930,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
if (sec_level > conn->sec_level)
conn->pending_sec_level = sec_level;
else if (conn->link_mode & HCI_LM_AUTH)
else if (test_bit(HCI_CONN_AUTH, &conn->flags))
return 1;
/* Make sure we preserve an existing MITM requirement*/
......@@ -889,7 +948,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* If we're already encrypted set the REAUTH_PEND flag,
* otherwise set the ENCRYPT_PEND.
*/
if (conn->link_mode & HCI_LM_ENCRYPT)
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
else
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
......@@ -930,7 +989,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return 1;
/* For other security levels we need the link key. */
if (!(conn->link_mode & HCI_LM_AUTH))
if (!test_bit(HCI_CONN_AUTH, &conn->flags))
goto auth;
/* An authenticated FIPS approved combination key has sufficient
......@@ -970,7 +1029,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return 0;
encrypt:
if (conn->link_mode & HCI_LM_ENCRYPT)
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
return 1;
hci_conn_encrypt(conn);
......@@ -1017,7 +1076,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
{
BT_DBG("hcon %p", conn);
if (!role && conn->link_mode & HCI_LM_MASTER)
if (!role && test_bit(HCI_CONN_MASTER, &conn->flags))
return 1;
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
......@@ -1038,9 +1097,6 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
BT_DBG("hcon %p mode %d", conn, conn->mode);
if (test_bit(HCI_RAW, &hdev->flags))
return;
if (conn->mode != HCI_CM_SNIFF)
goto timer;
......@@ -1091,6 +1147,28 @@ void hci_conn_check_pending(struct hci_dev *hdev)
hci_dev_unlock(hdev);
}
static u32 get_link_mode(struct hci_conn *conn)
{
u32 link_mode = 0;
if (test_bit(HCI_CONN_MASTER, &conn->flags))
link_mode |= HCI_LM_MASTER;
if (test_bit(HCI_CONN_ENCRYPT, &conn->flags))
link_mode |= HCI_LM_ENCRYPT;
if (test_bit(HCI_CONN_AUTH, &conn->flags))
link_mode |= HCI_LM_AUTH;
if (test_bit(HCI_CONN_SECURE, &conn->flags))
link_mode |= HCI_LM_SECURE;
if (test_bit(HCI_CONN_FIPS, &conn->flags))
link_mode |= HCI_LM_FIPS;
return link_mode;
}
int hci_get_conn_list(void __user *arg)
{
struct hci_conn *c;
......@@ -1126,7 +1204,7 @@ int hci_get_conn_list(void __user *arg)
(ci + n)->type = c->type;
(ci + n)->out = c->out;
(ci + n)->state = c->state;
(ci + n)->link_mode = c->link_mode;
(ci + n)->link_mode = get_link_mode(c);
if (++n >= req.conn_num)
break;
}
......@@ -1162,7 +1240,7 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
ci.type = conn->type;
ci.out = conn->out;
ci.state = conn->state;
ci.link_mode = conn->link_mode;
ci.link_mode = get_link_mode(conn);
}
hci_dev_unlock(hdev);
......
......@@ -35,6 +35,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/mgmt.h>
#include "smp.h"
......@@ -68,7 +69,7 @@ static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N';
buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
......@@ -94,7 +95,7 @@ static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
if (strtobool(buf, &enable))
return -EINVAL;
if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags))
if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
return -EALREADY;
hci_req_lock(hdev);
......@@ -115,7 +116,7 @@ static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
if (err < 0)
return err;
change_bit(HCI_DUT_MODE, &hdev->dev_flags);
change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
return count;
}
......@@ -190,6 +191,31 @@ static const struct file_operations blacklist_fops = {
.release = single_release,
};
static int whitelist_show(struct seq_file *f, void *p)
{
struct hci_dev *hdev = f->private;
struct bdaddr_list *b;
hci_dev_lock(hdev);
list_for_each_entry(b, &hdev->whitelist, list)
seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
hci_dev_unlock(hdev);
return 0;
}
static int whitelist_open(struct inode *inode, struct file *file)
{
return single_open(file, whitelist_show, inode->i_private);
}
static const struct file_operations whitelist_fops = {
.open = whitelist_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int uuids_show(struct seq_file *f, void *p)
{
struct hci_dev *hdev = f->private;
......@@ -352,62 +378,13 @@ static int auto_accept_delay_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
auto_accept_delay_set, "%llu\n");
static int ssp_debug_mode_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
struct sk_buff *skb;
__u8 mode;
int err;
if (val != 0 && val != 1)
return -EINVAL;
if (!test_bit(HCI_UP, &hdev->flags))
return -ENETDOWN;
hci_req_lock(hdev);
mode = val;
skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
&mode, HCI_CMD_TIMEOUT);
hci_req_unlock(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
err = -bt_to_errno(skb->data[0]);
kfree_skb(skb);
if (err < 0)
return err;
hci_dev_lock(hdev);
hdev->ssp_debug_mode = val;
hci_dev_unlock(hdev);
return 0;
}
static int ssp_debug_mode_get(void *data, u64 *val)
{
struct hci_dev *hdev = data;
hci_dev_lock(hdev);
*val = hdev->ssp_debug_mode;
hci_dev_unlock(hdev);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
ssp_debug_mode_set, "%llu\n");
static ssize_t force_sc_support_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_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
......@@ -432,10 +409,10 @@ static ssize_t force_sc_support_write(struct file *file,
if (strtobool(buf, &enable))
return -EINVAL;
if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
return -EALREADY;
change_bit(HCI_FORCE_SC, &hdev->dev_flags);
change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
return count;
}
......@@ -719,7 +696,7 @@ static ssize_t force_static_address_read(struct file *file,
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N';
buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
......@@ -744,10 +721,10 @@ static ssize_t force_static_address_write(struct file *file,
if (strtobool(buf, &enable))
return -EINVAL;
if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags))
if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
return -EALREADY;
change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags);
change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
return count;
}
......@@ -900,177 +877,113 @@ static int conn_max_interval_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
conn_max_interval_set, "%llu\n");
static int adv_channel_map_set(void *data, u64 val)
static int conn_latency_set(void *data, u64 val)
{
struct hci_dev *hdev = data;
if (val < 0x01 || val > 0x07)
if (val > 0x01f3)
return -EINVAL;
hci_dev_lock(hdev);
hdev->le_adv_channel_map = val;
hdev->le_conn_latency = val;
hci_dev_unlock(hdev);
return 0;
}
static int adv_channel_map_get(void *data, u64 *val)
static int conn_latency_get(void *data, u64 *val)
{
struct hci_dev *hdev = data;
hci_dev_lock(hdev);
*val = hdev->le_adv_channel_map;
*val = hdev->le_conn_latency;
hci_dev_unlock(hdev);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
adv_channel_map_set, "%llu\n");
static ssize_t lowpan_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_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
conn_latency_set, "%llu\n");
static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
size_t count, loff_t *position)
static int supervision_timeout_set(void *data, u64 val)
{
struct hci_dev *hdev = fp->private_data;
bool enable;
char buf[32];
size_t buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buffer, buf_size))
return -EFAULT;
buf[buf_size] = '\0';
struct hci_dev *hdev = data;
if (strtobool(buf, &enable) < 0)
if (val < 0x000a || val > 0x0c80)
return -EINVAL;
if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
return -EALREADY;
change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
hci_dev_lock(hdev);
hdev->le_supv_timeout = val;
hci_dev_unlock(hdev);
return count;
return 0;
}
static const struct file_operations lowpan_debugfs_fops = {
.open = simple_open,
.read = lowpan_read,
.write = lowpan_write,
.llseek = default_llseek,
};
static int le_auto_conn_show(struct seq_file *sf, void *ptr)
static int supervision_timeout_get(void *data, u64 *val)
{
struct hci_dev *hdev = sf->private;
struct hci_conn_params *p;
struct hci_dev *hdev = data;
hci_dev_lock(hdev);
list_for_each_entry(p, &hdev->le_conn_params, list) {
seq_printf(sf, "%pMR %u %u\n", &p->addr, p->addr_type,
p->auto_connect);
}
*val = hdev->le_supv_timeout;
hci_dev_unlock(hdev);
return 0;
}
static int le_auto_conn_open(struct inode *inode, struct file *file)
{
return single_open(file, le_auto_conn_show, inode->i_private);
}
DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
supervision_timeout_set, "%llu\n");
static ssize_t le_auto_conn_write(struct file *file, const char __user *data,
size_t count, loff_t *offset)
static int adv_channel_map_set(void *data, u64 val)
{
struct seq_file *sf = file->private_data;
struct hci_dev *hdev = sf->private;
u8 auto_connect = 0;
bdaddr_t addr;
u8 addr_type;
char *buf;
int err = 0;
int n;
/* Don't allow partial write */
if (*offset != 0)
return -EINVAL;
struct hci_dev *hdev = data;
if (count < 3)
if (val < 0x01 || val > 0x07)
return -EINVAL;
buf = memdup_user(data, count);
if (IS_ERR(buf))
return PTR_ERR(buf);
hci_dev_lock(hdev);
hdev->le_adv_channel_map = val;
hci_dev_unlock(hdev);
if (memcmp(buf, "add", 3) == 0) {
n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu %hhu",
&addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
&addr.b[1], &addr.b[0], &addr_type,
&auto_connect);
return 0;
}
if (n < 7) {
err = -EINVAL;
goto done;
}
static int adv_channel_map_get(void *data, u64 *val)
{
struct hci_dev *hdev = data;
hci_dev_lock(hdev);
err = hci_conn_params_add(hdev, &addr, addr_type, auto_connect,
hdev->le_conn_min_interval,
hdev->le_conn_max_interval);
*val = hdev->le_adv_channel_map;
hci_dev_unlock(hdev);
if (err)
goto done;
} else if (memcmp(buf, "del", 3) == 0) {
n = sscanf(&buf[4], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
&addr.b[5], &addr.b[4], &addr.b[3], &addr.b[2],
&addr.b[1], &addr.b[0], &addr_type);
return 0;
}
if (n < 7) {
err = -EINVAL;
goto done;
}
DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
adv_channel_map_set, "%llu\n");
static int device_list_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
struct hci_conn_params *p;
hci_dev_lock(hdev);
hci_conn_params_del(hdev, &addr, addr_type);
hci_dev_unlock(hdev);
} else if (memcmp(buf, "clr", 3) == 0) {
hci_dev_lock(hdev);
hci_conn_params_clear(hdev);
hci_pend_le_conns_clear(hdev);
hci_update_background_scan(hdev);
hci_dev_unlock(hdev);
} else {
err = -EINVAL;
list_for_each_entry(p, &hdev->le_conn_params, list) {
seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type,
p->auto_connect);
}
hci_dev_unlock(hdev);
done:
kfree(buf);
return 0;
}
if (err)
return err;
else
return count;
static int device_list_open(struct inode *inode, struct file *file)
{
return single_open(file, device_list_show, inode->i_private);
}
static const struct file_operations le_auto_conn_fops = {
.open = le_auto_conn_open,
static const struct file_operations device_list_fops = {
.open = device_list_open,
.read = seq_read,
.write = le_auto_conn_write,
.llseek = seq_lseek,
.release = single_release,
};
......@@ -1549,13 +1462,6 @@ static void hci_setup_event_mask(struct hci_request *req)
events[7] |= 0x20; /* LE Meta-Event */
hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
if (lmp_le_capable(hdev)) {
memset(events, 0, sizeof(events));
events[0] = 0x1f;
hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
sizeof(events), events);
}
}
static void hci_init2_req(struct hci_request *req, unsigned long opt)
......@@ -1688,7 +1594,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
}
/* Enable Authenticated Payload Timeout Expired event if supported */
if (lmp_ping_capable(hdev))
if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
events[2] |= 0x80;
hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
......@@ -1725,8 +1631,25 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
if (hdev->commands[5] & 0x10)
hci_setup_link_policy(req);
if (lmp_le_capable(hdev))
if (lmp_le_capable(hdev)) {
u8 events[8];
memset(events, 0, sizeof(events));
events[0] = 0x1f;
/* If controller supports the Connection Parameters Request
* Link Layer Procedure, enable the corresponding event.
*/
if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
events[0] |= 0x20; /* LE Remote Connection
* Parameter Request
*/
hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
events);
hci_set_le_support(req);
}
/* Read features beyond page 1 if available */
for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
......@@ -1752,7 +1675,7 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
/* Enable Secure Connections if supported and configured */
if ((lmp_sc_capable(hdev) ||
test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) &&
test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
u8 support = 0x01;
hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
......@@ -1809,6 +1732,8 @@ static int __hci_init(struct hci_dev *hdev)
debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
&blacklist_fops);
debugfs_create_file("whitelist", 0444, hdev->debugfs, hdev,
&whitelist_fops);
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
......@@ -1830,8 +1755,6 @@ static int __hci_init(struct hci_dev *hdev)
if (lmp_ssp_capable(hdev)) {
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops);
debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
hdev, &ssp_debug_mode_fops);
debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
hdev, &force_sc_support_fops);
debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
......@@ -1879,12 +1802,14 @@ static int __hci_init(struct hci_dev *hdev)
hdev, &conn_min_interval_fops);
debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
hdev, &conn_max_interval_fops);
debugfs_create_file("conn_latency", 0644, hdev->debugfs,
hdev, &conn_latency_fops);
debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
hdev, &supervision_timeout_fops);
debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
hdev, &adv_channel_map_fops);
debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
&lowpan_debugfs_fops);
debugfs_create_file("le_auto_conn", 0644, hdev->debugfs, hdev,
&le_auto_conn_fops);
debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
&device_list_fops);
debugfs_create_u16("discov_interleaved_timeout", 0644,
hdev->debugfs,
&hdev->discov_interleaved_timeout);
......@@ -1893,6 +1818,38 @@ static int __hci_init(struct hci_dev *hdev)
return 0;
}
static void hci_init0_req(struct hci_request *req, unsigned long opt)
{
struct hci_dev *hdev = req->hdev;
BT_DBG("%s %ld", hdev->name, opt);
/* Reset */
if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
hci_reset_req(req, 0);
/* Read Local Version */
hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
/* Read BD Address */
if (hdev->set_bdaddr)
hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
}
static int __hci_unconf_init(struct hci_dev *hdev)
{
int err;
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return 0;
err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
if (err < 0)
return err;
return 0;
}
static void hci_scan_req(struct hci_request *req, unsigned long opt)
{
__u8 scan = opt;
......@@ -1973,16 +1930,20 @@ bool hci_discovery_active(struct hci_dev *hdev)
void hci_discovery_set_state(struct hci_dev *hdev, int state)
{
int old_state = hdev->discovery.state;
BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
if (hdev->discovery.state == state)
if (old_state == state)
return;
hdev->discovery.state = state;
switch (state) {
case DISCOVERY_STOPPED:
hci_update_background_scan(hdev);
if (hdev->discovery.state != DISCOVERY_STARTING)
if (old_state != DISCOVERY_STARTING)
mgmt_discovering(hdev, 0);
break;
case DISCOVERY_STARTING:
......@@ -1995,8 +1956,6 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
case DISCOVERY_STOPPING:
break;
}
hdev->discovery.state = state;
}
void hci_inquiry_cache_flush(struct hci_dev *hdev)
......@@ -2083,22 +2042,24 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
list_add(&ie->list, pos);
}
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known, bool *ssp)
u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known)
{
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *ie;
u32 flags = 0;
BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
hci_remove_remote_oob_data(hdev, &data->bdaddr);
*ssp = data->ssp_mode;
if (!data->ssp_mode)
flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
if (ie) {
if (ie->data.ssp_mode)
*ssp = true;
if (!ie->data.ssp_mode)
flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
if (ie->name_state == NAME_NEEDED &&
data->rssi != ie->data.rssi) {
......@@ -2111,8 +2072,10 @@ bool 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_ATOMIC);
if (!ie)
return false;
if (!ie) {
flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
goto done;
}
list_add(&ie->all, &cache->all);
......@@ -2135,9 +2098,10 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
cache->timestamp = jiffies;
if (ie->name_state == NAME_NOT_KNOWN)
return false;
flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
return true;
done:
return flags;
}
static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
......@@ -2213,6 +2177,11 @@ int hci_inquiry(void __user *arg)
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
}
if (hdev->dev_type != HCI_BREDR) {
err = -EOPNOTSUPP;
goto done;
......@@ -2295,7 +2264,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
goto done;
}
if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
!test_bit(HCI_CONFIG, &hdev->dev_flags)) {
/* Check for rfkill but allow the HCI setup stage to
* proceed (which in itself doesn't cause any RF activity).
*/
......@@ -2338,14 +2308,47 @@ static int hci_dev_do_open(struct hci_dev *hdev)
atomic_set(&hdev->cmd_cnt, 1);
set_bit(HCI_INIT, &hdev->flags);
if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
if (hdev->setup)
ret = hdev->setup(hdev);
if (!ret) {
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
set_bit(HCI_RAW, &hdev->flags);
/* The transport driver can set these quirks before
* creating the HCI device or in its setup callback.
*
* In case any of them is set, the controller has to
* start up as unconfigured.
*/
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
/* For an unconfigured controller it is required to
* read at least the version information provided by
* the Read Local Version Information command.
*
* If the set_bdaddr driver callback is provided, then
* also the original Bluetooth public device address
* will be read using the Read BD Address command.
*/
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
ret = __hci_unconf_init(hdev);
}
if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
/* If public address change is configured, ensure that
* the address gets programmed. If the driver does not
* support changing the public address, fail the power
* on procedure.
*/
if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
hdev->set_bdaddr)
ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
else
ret = -EADDRNOTAVAIL;
}
if (!test_bit(HCI_RAW, &hdev->flags) &&
if (!ret) {
if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
ret = __hci_init(hdev);
}
......@@ -2358,6 +2361,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
set_bit(HCI_UP, &hdev->flags);
hci_notify(hdev, HCI_DEV_UP);
if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
!test_bit(HCI_CONFIG, &hdev->dev_flags) &&
!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
hdev->dev_type == HCI_BREDR) {
hci_dev_lock(hdev);
......@@ -2382,7 +2387,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
}
hdev->close(hdev);
hdev->flags = 0;
hdev->flags &= BIT(HCI_RAW);
}
done:
......@@ -2401,6 +2406,21 @@ int hci_dev_open(__u16 dev)
if (!hdev)
return -ENODEV;
/* Devices that are marked as unconfigured can only be powered
* up as user channel. Trying to bring them up as normal devices
* will result into a failure. Only user channel operation is
* possible.
*
* When this function is called for a user channel, the flag
* HCI_USER_CHANNEL will be set first before attempting to
* open the device.
*/
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
}
/* We need to ensure that no other power on/off work is pending
* before proceeding to call hci_dev_do_open. This is
* particularly important if the setup procedure has not yet
......@@ -2417,11 +2437,22 @@ int hci_dev_open(__u16 dev)
err = hci_dev_do_open(hdev);
done:
hci_dev_put(hdev);
return err;
}
/* This function requires the caller holds hdev->lock */
static void hci_pend_le_actions_clear(struct hci_dev *hdev)
{
struct hci_conn_params *p;
list_for_each_entry(p, &hdev->le_conn_params, list)
list_del_init(&p->action);
BT_DBG("All LE pending actions cleared");
}
static int hci_dev_do_close(struct hci_dev *hdev)
{
BT_DBG("%s %p", hdev->name, hdev);
......@@ -2432,7 +2463,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_req_lock(hdev);
if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
del_timer_sync(&hdev->cmd_timer);
cancel_delayed_work_sync(&hdev->cmd_timer);
hci_req_unlock(hdev);
return 0;
}
......@@ -2459,7 +2490,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock(hdev);
hci_inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
hci_pend_le_conns_clear(hdev);
hci_pend_le_actions_clear(hdev);
hci_dev_unlock(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
......@@ -2470,8 +2501,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
if (!test_bit(HCI_RAW, &hdev->flags) &&
!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
......@@ -2488,7 +2519,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Drop last sent command */
if (hdev->sent_cmd) {
del_timer_sync(&hdev->cmd_timer);
cancel_delayed_work_sync(&hdev->cmd_timer);
kfree_skb(hdev->sent_cmd);
hdev->sent_cmd = NULL;
}
......@@ -2501,7 +2532,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hdev->close(hdev);
/* Clear flags */
hdev->flags = 0;
hdev->flags &= BIT(HCI_RAW);
hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
......@@ -2570,6 +2601,11 @@ int hci_dev_reset(__u16 dev)
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);
......@@ -2585,7 +2621,6 @@ int hci_dev_reset(__u16 dev)
atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done:
......@@ -2608,6 +2643,11 @@ int hci_dev_reset_stat(__u16 dev)
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
ret = -EOPNOTSUPP;
goto done;
}
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
done:
......@@ -2633,6 +2673,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
}
if (hdev->dev_type != HCI_BREDR) {
err = -EOPNOTSUPP;
goto done;
......@@ -2670,6 +2715,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
case HCISETSCAN:
err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
HCI_INIT_TIMEOUT);
/* Ensure that the connectable state gets correctly
* notified if the whitelist is in use.
*/
if (!err && !list_empty(&hdev->whitelist)) {
bool changed;
if ((dr.dev_opt & SCAN_PAGE))
changed = !test_and_set_bit(HCI_CONNECTABLE,
&hdev->dev_flags);
else
changed = test_and_set_bit(HCI_CONNECTABLE,
&hdev->dev_flags);
if (changed)
mgmt_new_settings(hdev);
}
break;
case HCISETLINKPOL:
......@@ -2815,7 +2877,8 @@ static int hci_rfkill_set_block(void *data, bool blocked)
if (blocked) {
set_bit(HCI_RFKILLED, &hdev->dev_flags);
if (!test_bit(HCI_SETUP, &hdev->dev_flags))
if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
!test_bit(HCI_CONFIG, &hdev->dev_flags))
hci_dev_do_close(hdev);
} else {
clear_bit(HCI_RFKILLED, &hdev->dev_flags);
......@@ -2846,6 +2909,7 @@ static void hci_power_on(struct work_struct *work)
* valid, it is important to turn the device back off.
*/
if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
(hdev->dev_type == HCI_BREDR &&
!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!bacmp(&hdev->static_addr, BDADDR_ANY))) {
......@@ -2856,8 +2920,34 @@ static void hci_power_on(struct work_struct *work)
HCI_AUTO_OFF_TIMEOUT);
}
if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
/* For unconfigured devices, set the HCI_RAW flag
* so that userspace can easily identify them.
*/
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
set_bit(HCI_RAW, &hdev->flags);
/* For fully configured devices, this will send
* the Index Added event. For unconfigured devices,
* it will send Unconfigued Index Added event.
*
* Devices with HCI_QUIRK_RAW_DEVICE are ignored
* and no event will be send.
*/
mgmt_index_added(hdev);
} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
/* When the controller is now configured, then it
* is important to clear the HCI_RAW flag.
*/
if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
clear_bit(HCI_RAW, &hdev->flags);
/* Powering on the controller with HCI_CONFIG set only
* happens with the transition from unconfigured to
* configured. This will send the Index Added event.
*/
mgmt_index_added(hdev);
}
}
static void hci_power_off(struct work_struct *work)
......@@ -2974,10 +3064,7 @@ static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
static bool ltk_type_master(u8 type)
{
if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
return true;
return false;
return (type == SMP_LTK);
}
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
......@@ -3049,12 +3136,12 @@ struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
return NULL;
}
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
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 link_key *key, *old_key;
u8 old_key_type;
bool persistent;
old_key = hci_find_link_key(hdev, bdaddr);
if (old_key) {
......@@ -3064,7 +3151,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
old_key_type = conn ? conn->key_type : 0xff;
key = kzalloc(sizeof(*key), GFP_KERNEL);
if (!key)
return -ENOMEM;
return NULL;
list_add(&key->list, &hdev->link_keys);
}
......@@ -3089,17 +3176,11 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
else
key->type = type;
if (!new_key)
return 0;
persistent = hci_persistent_key(hdev, conn, type, old_key_type);
mgmt_new_link_key(hdev, key, persistent);
if (conn)
conn->flush_key = !persistent;
if (persistent)
*persistent = hci_persistent_key(hdev, conn, type,
old_key_type);
return 0;
return key;
}
struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
......@@ -3205,9 +3286,10 @@ void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
}
/* HCI command timer function */
static void hci_cmd_timeout(unsigned long arg)
static void hci_cmd_timeout(struct work_struct *work)
{
struct hci_dev *hdev = (void *) arg;
struct hci_dev *hdev = container_of(work, struct hci_dev,
cmd_timer.work);
if (hdev->sent_cmd) {
struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
......@@ -3313,12 +3395,12 @@ int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
return 0;
}
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *b;
list_for_each_entry(b, &hdev->blacklist, list) {
list_for_each_entry(b, bdaddr_list, list) {
if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
return b;
}
......@@ -3326,11 +3408,11 @@ struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
return NULL;
}
static void hci_blacklist_clear(struct hci_dev *hdev)
void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
{
struct list_head *p, *n;
list_for_each_safe(p, n, &hdev->blacklist) {
list_for_each_safe(p, n, bdaddr_list) {
struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
list_del(p);
......@@ -3338,14 +3420,14 @@ static void hci_blacklist_clear(struct hci_dev *hdev)
}
}
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
if (!bacmp(bdaddr, BDADDR_ANY))
return -EBADF;
if (hci_blacklist_lookup(hdev, bdaddr, type))
if (hci_bdaddr_list_lookup(list, bdaddr, type))
return -EEXIST;
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
......@@ -3355,82 +3437,21 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
bacpy(&entry->bdaddr, bdaddr);
entry->bdaddr_type = type;
list_add(&entry->list, &hdev->blacklist);
list_add(&entry->list, list);
return mgmt_device_blocked(hdev, bdaddr, type);
return 0;
}
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
if (!bacmp(bdaddr, BDADDR_ANY)) {
hci_blacklist_clear(hdev);
hci_bdaddr_list_clear(list);
return 0;
}
entry = hci_blacklist_lookup(hdev, bdaddr, type);
if (!entry)
return -ENOENT;
list_del(&entry->list);
kfree(entry);
return mgmt_device_unblocked(hdev, bdaddr, type);
}
struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *b;
list_for_each_entry(b, &hdev->le_white_list, list) {
if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
return b;
}
return NULL;
}
void hci_white_list_clear(struct hci_dev *hdev)
{
struct list_head *p, *n;
list_for_each_safe(p, n, &hdev->le_white_list) {
struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
list_del(p);
kfree(b);
}
}
int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
if (!bacmp(bdaddr, BDADDR_ANY))
return -EBADF;
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
if (!entry)
return -ENOMEM;
bacpy(&entry->bdaddr, bdaddr);
entry->bdaddr_type = type;
list_add(&entry->list, &hdev->le_white_list);
return 0;
}
int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
if (!bacmp(bdaddr, BDADDR_ANY))
return -EBADF;
entry = hci_white_list_lookup(hdev, bdaddr, type);
entry = hci_bdaddr_list_lookup(list, bdaddr, type);
if (!entry)
return -ENOENT;
......@@ -3446,6 +3467,10 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
{
struct hci_conn_params *params;
/* The conn params list only contains identity addresses */
if (!hci_is_identity_address(addr, addr_type))
return NULL;
list_for_each_entry(params, &hdev->le_conn_params, list) {
if (bacmp(&params->addr, addr) == 0 &&
params->addr_type == addr_type) {
......@@ -3473,62 +3498,97 @@ static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
return true;
}
static bool is_identity_address(bdaddr_t *addr, u8 addr_type)
/* This function requires the caller holds hdev->lock */
struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
bdaddr_t *addr, u8 addr_type)
{
if (addr_type == ADDR_LE_DEV_PUBLIC)
return true;
struct hci_conn_params *param;
/* Check for Random Static address type */
if ((addr->b[5] & 0xc0) == 0xc0)
return true;
/* The list only contains identity addresses */
if (!hci_is_identity_address(addr, addr_type))
return NULL;
return false;
list_for_each_entry(param, list, action) {
if (bacmp(&param->addr, addr) == 0 &&
param->addr_type == addr_type)
return param;
}
return NULL;
}
/* This function requires the caller holds hdev->lock */
int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
u8 auto_connect, u16 conn_min_interval,
u16 conn_max_interval)
struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type)
{
struct hci_conn_params *params;
if (!is_identity_address(addr, addr_type))
return -EINVAL;
if (!hci_is_identity_address(addr, addr_type))
return NULL;
params = hci_conn_params_lookup(hdev, addr, addr_type);
if (params)
goto update;
return params;
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params) {
BT_ERR("Out of memory");
return -ENOMEM;
return NULL;
}
bacpy(&params->addr, addr);
params->addr_type = addr_type;
list_add(&params->list, &hdev->le_conn_params);
INIT_LIST_HEAD(&params->action);
update:
params->conn_min_interval = conn_min_interval;
params->conn_max_interval = conn_max_interval;
params->auto_connect = auto_connect;
params->conn_min_interval = hdev->le_conn_min_interval;
params->conn_max_interval = hdev->le_conn_max_interval;
params->conn_latency = hdev->le_conn_latency;
params->supervision_timeout = hdev->le_supv_timeout;
params->auto_connect = HCI_AUTO_CONN_DISABLED;
BT_DBG("addr %pMR (type %u)", addr, addr_type);
return params;
}
/* This function requires the caller holds hdev->lock */
int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
u8 auto_connect)
{
struct hci_conn_params *params;
params = hci_conn_params_add(hdev, addr, addr_type);
if (!params)
return -EIO;
if (params->auto_connect == auto_connect)
return 0;
list_del_init(&params->action);
switch (auto_connect) {
case HCI_AUTO_CONN_DISABLED:
case HCI_AUTO_CONN_LINK_LOSS:
hci_pend_le_conn_del(hdev, addr, addr_type);
hci_update_background_scan(hdev);
break;
case HCI_AUTO_CONN_REPORT:
list_add(&params->action, &hdev->pend_le_reports);
hci_update_background_scan(hdev);
break;
case HCI_AUTO_CONN_ALWAYS:
if (!is_connected(hdev, addr, addr_type))
hci_pend_le_conn_add(hdev, addr, addr_type);
if (!is_connected(hdev, addr, addr_type)) {
list_add(&params->action, &hdev->pend_le_conns);
hci_update_background_scan(hdev);
}
break;
}
BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x "
"conn_max_interval 0x%.4x", addr, addr_type, auto_connect,
conn_min_interval, conn_max_interval);
params->auto_connect = auto_connect;
BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
auto_connect);
return 0;
}
......@@ -3542,97 +3602,44 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
if (!params)
return;
hci_pend_le_conn_del(hdev, addr, addr_type);
list_del(&params->action);
list_del(&params->list);
kfree(params);
hci_update_background_scan(hdev);
BT_DBG("addr %pMR (type %u)", addr, addr_type);
}
/* This function requires the caller holds hdev->lock */
void hci_conn_params_clear(struct hci_dev *hdev)
void hci_conn_params_clear_disabled(struct hci_dev *hdev)
{
struct hci_conn_params *params, *tmp;
list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
continue;
list_del(&params->list);
kfree(params);
}
BT_DBG("All LE connection parameters were removed");
}
/* This function requires the caller holds hdev->lock */
struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type)
{
struct bdaddr_list *entry;
list_for_each_entry(entry, &hdev->pend_le_conns, list) {
if (bacmp(&entry->bdaddr, addr) == 0 &&
entry->bdaddr_type == addr_type)
return entry;
}
return NULL;
BT_DBG("All LE disabled connection parameters were removed");
}
/* This function requires the caller holds hdev->lock */
void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
void hci_conn_params_clear_all(struct hci_dev *hdev)
{
struct bdaddr_list *entry;
entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
if (entry)
goto done;
struct hci_conn_params *params, *tmp;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
BT_ERR("Out of memory");
return;
list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
list_del(&params->action);
list_del(&params->list);
kfree(params);
}
bacpy(&entry->bdaddr, addr);
entry->bdaddr_type = addr_type;
list_add(&entry->list, &hdev->pend_le_conns);
BT_DBG("addr %pMR (type %u)", addr, addr_type);
done:
hci_update_background_scan(hdev);
}
/* This function requires the caller holds hdev->lock */
void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
{
struct bdaddr_list *entry;
entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
if (!entry)
goto done;
list_del(&entry->list);
kfree(entry);
BT_DBG("addr %pMR (type %u)", addr, addr_type);
done:
hci_update_background_scan(hdev);
}
/* This function requires the caller holds hdev->lock */
void hci_pend_le_conns_clear(struct hci_dev *hdev)
{
struct bdaddr_list *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
list_del(&entry->list);
kfree(entry);
}
BT_DBG("All LE pending connections cleared");
BT_DBG("All LE connection parameters were removed");
}
static void inquiry_complete(struct hci_dev *hdev, u8 status)
......@@ -3722,7 +3729,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
* In this kind of scenario skip the update and let the random
* address be updated at the next cycle.
*/
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
if (test_bit(HCI_LE_ADV, &hdev->dev_flags) ||
hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
BT_DBG("Deferring random address update");
return;
......@@ -3784,7 +3791,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
* the HCI command if the current random address is already the
* static one.
*/
if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
!bacmp(&hdev->bdaddr, BDADDR_ANY)) {
*own_addr_type = ADDR_LE_DEV_RANDOM;
if (bacmp(&hdev->static_addr, &hdev->random_addr))
......@@ -3813,7 +3820,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 *bdaddr_type)
{
if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
!bacmp(&hdev->bdaddr, BDADDR_ANY)) {
bacpy(bdaddr, &hdev->static_addr);
*bdaddr_type = ADDR_LE_DEV_RANDOM;
......@@ -3837,6 +3844,7 @@ struct hci_dev *hci_alloc_dev(void)
hdev->link_mode = (HCI_LM_ACCEPT);
hdev->num_iac = 0x01; /* One IAC support is mandatory */
hdev->io_capability = 0x03; /* No Input No Output */
hdev->manufacturer = 0xffff; /* Default to internal use */
hdev->inq_tx_power = HCI_TX_POWER_INVALID;
hdev->adv_tx_power = HCI_TX_POWER_INVALID;
......@@ -3848,6 +3856,8 @@ struct hci_dev *hci_alloc_dev(void)
hdev->le_scan_window = 0x0030;
hdev->le_conn_min_interval = 0x0028;
hdev->le_conn_max_interval = 0x0038;
hdev->le_conn_latency = 0x0000;
hdev->le_supv_timeout = 0x002a;
hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
......@@ -3859,6 +3869,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->mgmt_pending);
INIT_LIST_HEAD(&hdev->blacklist);
INIT_LIST_HEAD(&hdev->whitelist);
INIT_LIST_HEAD(&hdev->uuids);
INIT_LIST_HEAD(&hdev->link_keys);
INIT_LIST_HEAD(&hdev->long_term_keys);
......@@ -3867,6 +3878,7 @@ struct hci_dev *hci_alloc_dev(void)
INIT_LIST_HEAD(&hdev->le_white_list);
INIT_LIST_HEAD(&hdev->le_conn_params);
INIT_LIST_HEAD(&hdev->pend_le_conns);
INIT_LIST_HEAD(&hdev->pend_le_reports);
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_WORK(&hdev->rx_work, hci_rx_work);
......@@ -3884,7 +3896,7 @@ struct hci_dev *hci_alloc_dev(void)
init_waitqueue_head(&hdev->req_wait_q);
setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
hci_init_sysfs(hdev);
discovery_init(hdev);
......@@ -3906,7 +3918,7 @@ int hci_register_dev(struct hci_dev *hdev)
{
int id, error;
if (!hdev->open || !hdev->close)
if (!hdev->open || !hdev->close || !hdev->send)
return -EINVAL;
/* Do not allow HCI_AMP devices to register at index 0,
......@@ -3991,6 +4003,12 @@ int hci_register_dev(struct hci_dev *hdev)
list_add(&hdev->list, &hci_dev_list);
write_unlock(&hci_dev_list_lock);
/* Devices that are marked for raw-only usage are unconfigured
* and should not be included in normal operation.
*/
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
hci_notify(hdev, HCI_DEV_REG);
hci_dev_hold(hdev);
......@@ -4033,7 +4051,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
cancel_work_sync(&hdev->power_on);
if (!test_bit(HCI_INIT, &hdev->flags) &&
!test_bit(HCI_SETUP, &hdev->dev_flags)) {
!test_bit(HCI_SETUP, &hdev->dev_flags) &&
!test_bit(HCI_CONFIG, &hdev->dev_flags)) {
hci_dev_lock(hdev);
mgmt_index_removed(hdev);
hci_dev_unlock(hdev);
......@@ -4061,15 +4080,15 @@ void hci_unregister_dev(struct hci_dev *hdev)
destroy_workqueue(hdev->req_workqueue);
hci_dev_lock(hdev);
hci_blacklist_clear(hdev);
hci_bdaddr_list_clear(&hdev->blacklist);
hci_bdaddr_list_clear(&hdev->whitelist);
hci_uuids_clear(hdev);
hci_link_keys_clear(hdev);
hci_smp_ltks_clear(hdev);
hci_smp_irks_clear(hdev);
hci_remote_oob_data_clear(hdev);
hci_white_list_clear(hdev);
hci_conn_params_clear(hdev);
hci_pend_le_conns_clear(hdev);
hci_bdaddr_list_clear(&hdev->le_white_list);
hci_conn_params_clear_all(hdev);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
......@@ -4307,6 +4326,8 @@ EXPORT_SYMBOL(hci_unregister_cb);
static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
int err;
BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
/* Time stamp */
......@@ -4323,8 +4344,11 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
/* Get rid of skb owner, prior to sending to the driver. */
skb_orphan(skb);
if (hdev->send(hdev, skb) < 0)
BT_ERR("%s sending frame failed", hdev->name);
err = hdev->send(hdev, skb);
if (err < 0) {
BT_ERR("%s sending frame failed (%d)", hdev->name, err);
kfree_skb(skb);
}
}
void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
......@@ -4798,7 +4822,7 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
{
if (!test_bit(HCI_RAW, &hdev->flags)) {
if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if (!cnt && time_after(jiffies, hdev->acl_last_tx +
......@@ -4981,7 +5005,7 @@ static void hci_sched_le(struct hci_dev *hdev)
if (!hci_conn_num(hdev, LE_LINK))
return;
if (!test_bit(HCI_RAW, &hdev->flags)) {
if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
/* LE tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if (!hdev->le_cnt && hdev->le_pkts &&
......@@ -5226,8 +5250,7 @@ static void hci_rx_work(struct work_struct *work)
hci_send_to_sock(hdev, skb);
}
if (test_bit(HCI_RAW, &hdev->flags) ||
test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
kfree_skb(skb);
continue;
}
......@@ -5287,10 +5310,10 @@ static void hci_cmd_work(struct work_struct *work)
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(hdev, skb);
if (test_bit(HCI_RESET, &hdev->flags))
del_timer(&hdev->cmd_timer);
cancel_delayed_work(&hdev->cmd_timer);
else
mod_timer(&hdev->cmd_timer,
jiffies + HCI_CMD_TIMEOUT);
schedule_delayed_work(&hdev->cmd_timer,
HCI_CMD_TIMEOUT);
} else {
skb_queue_head(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);
......@@ -5314,12 +5337,13 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
struct hci_dev *hdev = req->hdev;
u8 own_addr_type;
/* Set require_privacy to true to avoid identification from
* unknown peer devices. Since this is passive scanning, no
* SCAN_REQ using the local identity should be sent. Mandating
* privacy is just an extra precaution.
/* Set require_privacy to false since no SCAN_REQ are send
* during passive scanning. Not using an unresolvable address
* here is important so that peer devices using direct
* advertising with our address will be correctly reported
* by the controller.
*/
if (hci_update_random_address(req, true, &own_addr_type))
if (hci_update_random_address(req, false, &own_addr_type))
return;
memset(&param_cp, 0, sizeof(param_cp));
......@@ -5356,11 +5380,30 @@ void hci_update_background_scan(struct hci_dev *hdev)
struct hci_conn *conn;
int err;
if (!test_bit(HCI_UP, &hdev->flags) ||
test_bit(HCI_INIT, &hdev->flags) ||
test_bit(HCI_SETUP, &hdev->dev_flags) ||
test_bit(HCI_CONFIG, &hdev->dev_flags) ||
test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
test_bit(HCI_UNREGISTER, &hdev->dev_flags))
return;
/* No point in doing scanning if LE support hasn't been enabled */
if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
return;
/* If discovery is active don't interfere with it */
if (hdev->discovery.state != DISCOVERY_STOPPED)
return;
hci_req_init(&req, hdev);
if (list_empty(&hdev->pend_le_conns)) {
/* If there is no pending LE connections, we should stop
* the background scanning.
if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
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
* scanning.
*/
/* If controller is not scanning we are done. */
......
......@@ -32,6 +32,7 @@
#include "a2mp.h"
#include "amp.h"
#include "smp.h"
/* Handle HCI Event packets */
......@@ -102,9 +103,9 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
if (conn) {
if (rp->role)
conn->link_mode &= ~HCI_LM_MASTER;
clear_bit(HCI_CONN_MASTER, &conn->flags);
else
conn->link_mode |= HCI_LM_MASTER;
set_bit(HCI_CONN_MASTER, &conn->flags);
}
hci_dev_unlock(hdev);
......@@ -174,11 +175,13 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
if (!sent)
return;
if (!status)
hdev->link_policy = get_unaligned_le16(sent);
}
......@@ -269,27 +272,30 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
__u8 param;
void *sent;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
if (!sent)
return;
if (!status) {
__u8 param = *((__u8 *) sent);
param = *((__u8 *) sent);
if (param)
set_bit(HCI_ENCRYPT, &hdev->flags);
else
clear_bit(HCI_ENCRYPT, &hdev->flags);
}
}
static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 param, status = *((__u8 *) skb->data);
__u8 status = *((__u8 *) skb->data);
__u8 param;
int old_pscan, old_iscan;
void *sent;
......@@ -601,7 +607,9 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
hdev->flow_ctl_mode = rp->mode;
}
......@@ -637,8 +645,14 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
if (test_bit(HCI_INIT, &hdev->flags))
bacpy(&hdev->bdaddr, &rp->bdaddr);
if (test_bit(HCI_SETUP, &hdev->dev_flags))
bacpy(&hdev->setup_addr, &rp->bdaddr);
}
static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
......@@ -648,7 +662,10 @@ static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
if (rp->status)
return;
if (test_bit(HCI_INIT, &hdev->flags)) {
hdev->page_scan_interval = __le16_to_cpu(rp->interval);
hdev->page_scan_window = __le16_to_cpu(rp->window);
}
......@@ -680,7 +697,10 @@ static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
if (rp->status)
return;
if (test_bit(HCI_INIT, &hdev->flags))
hdev->page_scan_type = rp->type;
}
......@@ -720,6 +740,41 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev,
hdev->block_cnt, hdev->block_len);
}
static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_clock *rp = (void *) skb->data;
struct hci_cp_read_clock *cp;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
if (skb->len < sizeof(*rp))
return;
if (rp->status)
return;
hci_dev_lock(hdev);
cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
if (!cp)
goto unlock;
if (cp->which == 0x00) {
hdev->clock = le32_to_cpu(rp->clock);
goto unlock;
}
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
if (conn) {
conn->clock = le32_to_cpu(rp->clock);
conn->clock_accuracy = le16_to_cpu(rp->accuracy);
}
unlock:
hci_dev_unlock(hdev);
}
static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
struct sk_buff *skb)
{
......@@ -789,7 +844,9 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
hdev->inq_tx_power = rp->tx_power;
}
......@@ -861,7 +918,9 @@ static void hci_cc_le_read_local_features(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
memcpy(hdev->le_features, rp->features, 8);
}
......@@ -872,7 +931,9 @@ static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
hdev->adv_tx_power = rp->tx_power;
}
......@@ -973,13 +1034,15 @@ static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
if (!sent)
return;
hci_dev_lock(hdev);
if (!status)
bacpy(&hdev->random_addr, sent);
hci_dev_unlock(hdev);
......@@ -991,11 +1054,11 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%2.2x", hdev->name, status);
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
if (!sent)
if (status)
return;
if (status)
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
if (!sent)
return;
hci_dev_lock(hdev);
......@@ -1006,15 +1069,17 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
if (*sent) {
struct hci_conn *conn;
set_bit(HCI_LE_ADV, &hdev->dev_flags);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (conn)
queue_delayed_work(hdev->workqueue,
&conn->le_conn_timeout,
HCI_LE_CONN_TIMEOUT);
conn->conn_timeout);
} else {
clear_bit(HCI_LE_ADV, &hdev->dev_flags);
}
mgmt_advertising(hdev, *sent);
hci_dev_unlock(hdev);
}
......@@ -1025,13 +1090,15 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
if (!cp)
return;
hci_dev_lock(hdev);
if (!status)
hdev->le_scan_type = cp->type;
hci_dev_unlock(hdev);
......@@ -1053,13 +1120,15 @@ static void clear_pending_adv_report(struct hci_dev *hdev)
}
static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
u8 bdaddr_type, s8 rssi, u32 flags,
u8 *data, u8 len)
{
struct discovery_state *d = &hdev->discovery;
bacpy(&d->last_adv_addr, bdaddr);
d->last_adv_addr_type = bdaddr_type;
d->last_adv_rssi = rssi;
d->last_adv_flags = flags;
memcpy(d->last_adv_data, data, len);
d->last_adv_data_len = len;
}
......@@ -1072,11 +1141,11 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
if (!cp)
if (status)
return;
if (status)
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
if (!cp)
return;
switch (cp->enable) {
......@@ -1096,7 +1165,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL,
d->last_adv_rssi, 0, 1,
d->last_adv_rssi, d->last_adv_flags,
d->last_adv_data,
d->last_adv_data_len, NULL, 0);
}
......@@ -1107,13 +1176,21 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
cancel_delayed_work(&hdev->le_scan_disable);
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
* interrupted scanning due to a connect request. Mark
* therefore discovery as stopped.
* therefore discovery as stopped. If this was not
* because of a connect request advertising might have
* been disabled because of active scanning, so
* re-enable it again if necessary.
*/
if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
&hdev->dev_flags))
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
else if (!test_bit(HCI_LE_ADV, &hdev->dev_flags) &&
hdev->discovery.state == DISCOVERY_FINDING)
mgmt_reenable_advertising(hdev);
break;
default:
......@@ -1129,7 +1206,9 @@ static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
if (!rp->status)
if (rp->status)
return;
hdev->le_white_list_size = rp->size;
}
......@@ -1140,8 +1219,10 @@ static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (!status)
hci_white_list_clear(hdev);
if (status)
return;
hci_bdaddr_list_clear(&hdev->le_white_list);
}
static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
......@@ -1152,12 +1233,15 @@ static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
if (!sent)
return;
if (!status)
hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr,
sent->bdaddr_type);
}
static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
......@@ -1168,12 +1252,15 @@ static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
if (!sent)
return;
if (!status)
hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr,
sent->bdaddr_type);
}
static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
......@@ -1183,7 +1270,9 @@ static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status)
if (rp->status)
return;
memcpy(hdev->le_states, rp->le_states, 8);
}
......@@ -1195,11 +1284,13 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
if (!sent)
return;
if (!status) {
if (sent->le) {
hdev->features[1][0] |= LMP_HOST_LE;
set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
......@@ -1213,7 +1304,6 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
hdev->features[1][0] |= LMP_HOST_LE_BREDR;
else
hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
}
}
static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -1345,7 +1435,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
if (conn) {
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
set_bit(HCI_CONN_MASTER, &conn->flags);
} else
BT_ERR("No memory for new connection");
}
......@@ -1835,7 +1925,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
queue_delayed_work(conn->hdev->workqueue,
&conn->le_conn_timeout,
HCI_LE_CONN_TIMEOUT);
conn->conn_timeout);
unlock:
hci_dev_unlock(hdev);
......@@ -1929,7 +2019,7 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
bool name_known, ssp;
u32 flags;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
......@@ -1940,10 +2030,10 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
data.rssi = 0x00;
data.ssp_mode = 0x00;
name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
flags = hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, 0, !name_known, ssp, NULL,
0, NULL, 0);
info->dev_class, 0, flags, NULL, 0, NULL, 0);
}
hci_dev_unlock(hdev);
......@@ -1988,10 +2078,10 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_add_sysfs(conn);
if (test_bit(HCI_AUTH, &hdev->flags))
conn->link_mode |= HCI_LM_AUTH;
set_bit(HCI_CONN_AUTH, &conn->flags);
if (test_bit(HCI_ENCRYPT, &hdev->flags))
conn->link_mode |= HCI_LM_ENCRYPT;
set_bit(HCI_CONN_ENCRYPT, &conn->flags);
/* Get remote features */
if (conn->type == ACL_LINK) {
......@@ -2031,10 +2121,21 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_check_pending(hdev);
}
static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct hci_cp_reject_conn_req cp;
bacpy(&cp.bdaddr, bdaddr);
cp.reason = HCI_ERROR_REJ_BAD_ADDR;
hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
}
static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_conn_request *ev = (void *) skb->data;
int mask = hdev->link_mode;
struct inquiry_entry *ie;
struct hci_conn *conn;
__u8 flags = 0;
BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
......@@ -2043,11 +2144,26 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
&flags);
if ((mask & HCI_LM_ACCEPT) &&
!hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
if (!(mask & HCI_LM_ACCEPT)) {
hci_reject_conn(hdev, &ev->bdaddr);
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;
}
}
/* Connection accepted */
struct inquiry_entry *ie;
struct hci_conn *conn;
hci_dev_lock(hdev);
......@@ -2082,8 +2198,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
else
cp.role = 0x01; /* Remain slave */
hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
&cp);
hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
} else if (!(flags & HCI_PROTO_DEFER)) {
struct hci_cp_accept_sync_conn_req cp;
conn->state = BT_CONNECT;
......@@ -2097,20 +2212,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
cp.content_format = cpu_to_le16(hdev->voice_setting);
cp.retrans_effort = 0xff;
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp);
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
&cp);
} else {
conn->state = BT_CONNECT2;
hci_proto_connect_cfm(conn, 0);
}
} else {
/* Connection rejected */
struct hci_cp_reject_conn_req cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.reason = HCI_ERROR_REJ_BAD_ADDR;
hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
}
}
static u8 hci_to_mgmt_reason(u8 err)
......@@ -2158,7 +2265,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
reason, mgmt_connected);
if (conn->type == ACL_LINK && conn->flush_key)
if (conn->type == ACL_LINK &&
test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
hci_remove_link_key(hdev, &conn->dst);
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
......@@ -2170,7 +2278,9 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
/* Fall through */
case HCI_AUTO_CONN_ALWAYS:
hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
list_del_init(&params->action);
list_add(&params->action, &hdev->pend_le_conns);
hci_update_background_scan(hdev);
break;
default:
......@@ -2218,7 +2328,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
BT_INFO("re-auth of legacy device is not possible.");
} else {
conn->link_mode |= HCI_LM_AUTH;
set_bit(HCI_CONN_AUTH, &conn->flags);
conn->sec_level = conn->pending_sec_level;
}
} else {
......@@ -2321,19 +2431,19 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (!ev->status) {
if (ev->encrypt) {
/* Encryption implies authentication */
conn->link_mode |= HCI_LM_AUTH;
conn->link_mode |= HCI_LM_ENCRYPT;
set_bit(HCI_CONN_AUTH, &conn->flags);
set_bit(HCI_CONN_ENCRYPT, &conn->flags);
conn->sec_level = conn->pending_sec_level;
/* P-256 authentication key implies FIPS */
if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
conn->link_mode |= HCI_LM_FIPS;
set_bit(HCI_CONN_FIPS, &conn->flags);
if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
conn->type == LE_LINK)
set_bit(HCI_CONN_AES_CCM, &conn->flags);
} else {
conn->link_mode &= ~HCI_LM_ENCRYPT;
clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
clear_bit(HCI_CONN_AES_CCM, &conn->flags);
}
}
......@@ -2384,7 +2494,7 @@ static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
if (!ev->status)
conn->link_mode |= HCI_LM_SECURE;
set_bit(HCI_CONN_SECURE, &conn->flags);
clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
......@@ -2595,6 +2705,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_read_local_amp_info(hdev, skb);
break;
case HCI_OP_READ_CLOCK:
hci_cc_read_clock(hdev, skb);
break;
case HCI_OP_READ_LOCAL_AMP_ASSOC:
hci_cc_read_local_amp_assoc(hdev, skb);
break;
......@@ -2709,7 +2823,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
if (opcode != HCI_OP_NOP)
del_timer(&hdev->cmd_timer);
cancel_delayed_work(&hdev->cmd_timer);
hci_req_cmd_complete(hdev, opcode, status);
......@@ -2800,7 +2914,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
if (opcode != HCI_OP_NOP)
del_timer(&hdev->cmd_timer);
cancel_delayed_work(&hdev->cmd_timer);
if (ev->status ||
(hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
......@@ -2826,9 +2940,9 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (conn) {
if (!ev->status) {
if (ev->role)
conn->link_mode &= ~HCI_LM_MASTER;
clear_bit(HCI_CONN_MASTER, &conn->flags);
else
conn->link_mode |= HCI_LM_MASTER;
set_bit(HCI_CONN_MASTER, &conn->flags);
}
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
......@@ -3065,12 +3179,6 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
&ev->bdaddr);
if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
key->type == HCI_LK_DEBUG_COMBINATION) {
BT_DBG("%s ignoring debug key", hdev->name);
goto not_found;
}
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) {
if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
......@@ -3110,6 +3218,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_link_key_notify *ev = (void *) skb->data;
struct hci_conn *conn;
struct link_key *key;
bool persistent;
u8 pin_len = 0;
BT_DBG("%s", hdev->name);
......@@ -3128,10 +3238,33 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_conn_drop(conn);
}
if (test_bit(HCI_MGMT, &hdev->dev_flags))
hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
goto unlock;
key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len, &persistent);
if (!key)
goto unlock;
mgmt_new_link_key(hdev, key, persistent);
/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
* is set. If it's not set simply remove the key from the kernel
* list (we've still notified user space about it but with
* store_hint being 0).
*/
if (key->type == HCI_LK_DEBUG_COMBINATION &&
!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
list_del(&key->list);
kfree(key);
} else if (conn) {
if (persistent)
clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
else
set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
}
unlock:
hci_dev_unlock(hdev);
}
......@@ -3197,7 +3330,6 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
{
struct inquiry_data data;
int num_rsp = *((__u8 *) skb->data);
bool name_known, ssp;
BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
......@@ -3214,6 +3346,8 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
info = (void *) (skb->data + 1);
for (; num_rsp; num_rsp--, info++) {
u32 flags;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
......@@ -3223,16 +3357,18 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
data.rssi = info->rssi;
data.ssp_mode = 0x00;
name_known = hci_inquiry_cache_update(hdev, &data,
false, &ssp);
flags = hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
!name_known, ssp, NULL, 0, NULL, 0);
flags, NULL, 0, NULL, 0);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
for (; num_rsp; num_rsp--, info++) {
u32 flags;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
......@@ -3241,11 +3377,12 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
name_known = hci_inquiry_cache_update(hdev, &data,
false, &ssp);
flags = hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
!name_known, ssp, NULL, 0, NULL, 0);
flags, NULL, 0, NULL, 0);
}
}
......@@ -3348,6 +3485,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
hci_conn_add_sysfs(conn);
break;
case 0x10: /* Connection Accept Timeout */
case 0x0d: /* Connection Rejected due to Limited Resources */
case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */
......@@ -3411,7 +3549,8 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
bool name_known, ssp;
u32 flags;
bool name_known;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
......@@ -3429,12 +3568,13 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
else
name_known = true;
name_known = hci_inquiry_cache_update(hdev, &data, name_known,
&ssp);
flags = hci_inquiry_cache_update(hdev, &data, name_known);
eir_len = eir_get_length(info->data, sizeof(info->data));
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi, !name_known,
ssp, info->data, eir_len, NULL, 0);
info->dev_class, info->rssi,
flags, info->data, eir_len, NULL, 0);
}
hci_dev_unlock(hdev);
......@@ -3967,13 +4107,20 @@ static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
struct hci_conn_params *params;
struct hci_conn *conn;
struct smp_irk *irk;
u8 addr_type;
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
hci_dev_lock(hdev);
/* All controllers implicitly stop advertising in the event of a
* connection, so ensure that the state bit is cleared.
*/
clear_bit(HCI_LE_ADV, &hdev->dev_flags);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (!conn) {
conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
......@@ -3986,7 +4133,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (ev->role == LE_CONN_ROLE_MASTER) {
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
set_bit(HCI_CONN_MASTER, &conn->flags);
}
/* If we didn't have a hci_conn object previously
......@@ -4025,6 +4172,14 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->init_addr_type = ev->bdaddr_type;
bacpy(&conn->init_addr, &ev->bdaddr);
/* For incoming connections, set the default minimum
* and maximum connection interval. They will be used
* to check if the parameters are in range and if not
* trigger the connection update procedure.
*/
conn->le_conn_min_interval = hdev->le_conn_min_interval;
conn->le_conn_max_interval = hdev->le_conn_max_interval;
}
/* Lookup the identity address from the stored connection
......@@ -4042,6 +4197,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->dst_type = irk->addr_type;
}
if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
addr_type = BDADDR_LE_PUBLIC;
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);
goto unlock;
}
if (ev->status) {
hci_le_conn_failed(conn, ev->status);
goto unlock;
......@@ -4055,40 +4221,75 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED;
if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
set_bit(HCI_CONN_6LOWPAN, &conn->flags);
conn->le_conn_interval = le16_to_cpu(ev->interval);
conn->le_conn_latency = le16_to_cpu(ev->latency);
conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
hci_conn_add_sysfs(conn);
hci_proto_connect_cfm(conn, ev->status);
hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
if (params)
list_del_init(&params->action);
unlock:
hci_update_background_scan(hdev);
hci_dev_unlock(hdev);
}
static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_le_conn_update_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
if (ev->status)
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
conn->le_conn_interval = le16_to_cpu(ev->interval);
conn->le_conn_latency = le16_to_cpu(ev->latency);
conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
}
hci_dev_unlock(hdev);
}
/* This function requires the caller holds hdev->lock */
static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
u8 addr_type)
u8 addr_type, u8 adv_type)
{
struct hci_conn *conn;
struct smp_irk *irk;
/* If this is a resolvable address, we should resolve it and then
* update address and address type variables.
*/
irk = hci_get_irk(hdev, addr, addr_type);
if (irk) {
addr = &irk->bdaddr;
addr_type = irk->addr_type;
}
/* If the event is not connectable don't proceed further */
if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
return;
/* Ignore if the device is blocked */
if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
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)
goto connect;
if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
/* If we're not connectable only connect devices that we have in
* our pend_le_conns list.
*/
if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type))
return;
connect:
/* Request connection in master = true role */
conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
HCI_AT_NO_BONDING);
HCI_LE_AUTOCONN_TIMEOUT, true);
if (!IS_ERR(conn))
return;
......@@ -4109,15 +4310,65 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
{
struct discovery_state *d = &hdev->discovery;
struct smp_irk *irk;
bool match;
u32 flags;
/* Check if we need to convert to identity address */
irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
if (irk) {
bdaddr = &irk->bdaddr;
bdaddr_type = irk->addr_type;
}
/* Check if we have been requested to connect to this device */
check_pending_le_conn(hdev, bdaddr, bdaddr_type, type);
/* Passive scanning shouldn't trigger any device found events */
/* Passive scanning shouldn't trigger any device found events,
* except for devices marked as CONN_REPORT for which we do send
* device found events.
*/
if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
check_pending_le_conn(hdev, bdaddr, bdaddr_type);
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)
return;
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
else
flags = 0;
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, flags, data, len, NULL, 0);
return;
}
/* When receiving non-connectable or scannable undirected
* advertising reports, this means that the remote device is
* not connectable and then clearly indicate this in the
* device found event.
*
* When receiving a scan response, then there is no way to
* know if the remote device is connectable or not. However
* since scan responses are merged with a previously seen
* advertising report, the flags field from that report
* will be used.
*
* In the really unlikely case that a controller get confused
* and just sends a scan response event, then it is marked as
* not connectable as well.
*/
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
type == LE_ADV_SCAN_RSP)
flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
else
flags = 0;
/* If there's nothing pending either store the data from this
* event or send an immediate device found event if the data
* should not be stored for later.
......@@ -4128,12 +4379,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, data, len);
rssi, flags, data, len);
return;
}
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, 0, 1, data, len, NULL, 0);
rssi, flags, data, len, NULL, 0);
return;
}
......@@ -4150,7 +4401,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
if (!match)
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL,
d->last_adv_rssi, 0, 1,
d->last_adv_rssi, d->last_adv_flags,
d->last_adv_data,
d->last_adv_data_len, NULL, 0);
......@@ -4159,7 +4410,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, data, len);
rssi, flags, data, len);
return;
}
......@@ -4168,7 +4419,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/
clear_pending_adv_report(hdev);
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, 0, 1, data, len, NULL, 0);
rssi, flags, data, len, NULL, 0);
return;
}
......@@ -4177,8 +4428,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
* sending a merged device found event.
*/
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
d->last_adv_data, d->last_adv_data_len);
d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
d->last_adv_data, d->last_adv_data_len, data, len);
clear_pending_adv_report(hdev);
}
......@@ -4241,9 +4492,12 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
* distribute the keys. Later, security can be re-established
* using a distributed LTK.
*/
if (ltk->type == HCI_SMP_STK_SLAVE) {
if (ltk->type == SMP_STK) {
set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
list_del(&ltk->list);
kfree(ltk);
} else {
clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
}
hci_dev_unlock(hdev);
......@@ -4256,6 +4510,76 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev);
}
static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
u8 reason)
{
struct hci_cp_le_conn_param_req_neg_reply cp;
cp.handle = cpu_to_le16(handle);
cp.reason = reason;
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
&cp);
}
static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data;
struct hci_cp_le_conn_param_req_reply cp;
struct hci_conn *hcon;
u16 handle, min, max, latency, timeout;
handle = le16_to_cpu(ev->handle);
min = le16_to_cpu(ev->interval_min);
max = le16_to_cpu(ev->interval_max);
latency = le16_to_cpu(ev->latency);
timeout = le16_to_cpu(ev->timeout);
hcon = hci_conn_hash_lookup_handle(hdev, handle);
if (!hcon || hcon->state != BT_CONNECTED)
return send_conn_param_neg_reply(hdev, handle,
HCI_ERROR_UNKNOWN_CONN_ID);
if (hci_check_conn_params(min, max, latency, timeout))
return send_conn_param_neg_reply(hdev, handle,
HCI_ERROR_INVALID_LL_PARAMS);
if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
struct hci_conn_params *params;
u8 store_hint;
hci_dev_lock(hdev);
params = hci_conn_params_lookup(hdev, &hcon->dst,
hcon->dst_type);
if (params) {
params->conn_min_interval = min;
params->conn_max_interval = max;
params->conn_latency = latency;
params->supervision_timeout = timeout;
store_hint = 0x01;
} else{
store_hint = 0x00;
}
hci_dev_unlock(hdev);
mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
store_hint, min, max, latency, timeout);
}
cp.handle = ev->handle;
cp.interval_min = ev->interval_min;
cp.interval_max = ev->interval_max;
cp.latency = ev->latency;
cp.timeout = ev->timeout;
cp.min_ce_len = 0;
cp.max_ce_len = 0;
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
}
static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_meta *le_ev = (void *) skb->data;
......@@ -4267,6 +4591,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_le_conn_complete_evt(hdev, skb);
break;
case HCI_EV_LE_CONN_UPDATE_COMPLETE:
hci_le_conn_update_complete_evt(hdev, skb);
break;
case HCI_EV_LE_ADVERTISING_REPORT:
hci_le_adv_report_evt(hdev, skb);
break;
......@@ -4275,6 +4603,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_le_ltk_request_evt(hdev, skb);
break;
case HCI_EV_LE_REMOTE_CONN_PARAM_REQ:
hci_le_remote_conn_param_req_evt(hdev, skb);
break;
default:
break;
}
......
......@@ -481,7 +481,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_add(hdev, &bdaddr, BDADDR_BREDR);
err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
hci_dev_unlock(hdev);
......@@ -498,7 +498,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_del(hdev, &bdaddr, BDADDR_BREDR);
err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
hci_dev_unlock(hdev);
......@@ -517,6 +517,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
return -EBUSY;
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
return -EOPNOTSUPP;
if (hdev->dev_type != HCI_BREDR)
return -EOPNOTSUPP;
......@@ -690,7 +693,8 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
if (test_bit(HCI_UP, &hdev->flags) ||
test_bit(HCI_INIT, &hdev->flags) ||
test_bit(HCI_SETUP, &hdev->dev_flags)) {
test_bit(HCI_SETUP, &hdev->dev_flags) ||
test_bit(HCI_CONFIG, &hdev->dev_flags)) {
err = -EBUSY;
hci_dev_put(hdev);
goto done;
......@@ -960,7 +964,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto drop;
}
if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
if (ogf == 0x3f) {
skb_queue_tail(&hdev->raw_q, skb);
queue_work(hdev->workqueue, &hdev->tx_work);
} else {
......
......@@ -40,7 +40,6 @@
#include "smp.h"
#include "a2mp.h"
#include "amp.h"
#include "6lowpan.h"
#define LE_FLOWCTL_MAX_CREDITS 65535
......@@ -205,6 +204,7 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
write_unlock(&chan_list_lock);
return err;
}
EXPORT_SYMBOL_GPL(l2cap_add_psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
{
......@@ -437,6 +437,7 @@ struct l2cap_chan *l2cap_chan_create(void)
return chan;
}
EXPORT_SYMBOL_GPL(l2cap_chan_create);
static void l2cap_chan_destroy(struct kref *kref)
{
......@@ -464,6 +465,7 @@ void l2cap_chan_put(struct l2cap_chan *c)
kref_put(&c->kref, l2cap_chan_destroy);
}
EXPORT_SYMBOL_GPL(l2cap_chan_put);
void l2cap_chan_set_defaults(struct l2cap_chan *chan)
{
......@@ -482,6 +484,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
}
EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults);
static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
{
......@@ -614,6 +617,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
return;
}
EXPORT_SYMBOL_GPL(l2cap_chan_del);
void l2cap_conn_update_id_addr(struct hci_conn *hcon)
{
......@@ -717,6 +721,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
break;
}
}
EXPORT_SYMBOL(l2cap_chan_close);
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
......@@ -1455,13 +1460,12 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{
struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev;
struct l2cap_chan *chan, *pchan;
u8 dst_type;
BT_DBG("");
bt_6lowpan_add_conn(conn);
/* Check if we have socket listening on cid */
pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
&hcon->src, &hcon->dst);
......@@ -1475,9 +1479,28 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
dst_type = bdaddr_type(hcon, hcon->dst_type);
/* If device is blocked, do not create a channel for it */
if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type))
return;
/* For LE slave connections, make sure the connection interval
* is in the range of the minium and maximum interval that has
* been configured for this connection. If not, then trigger
* the connection update procedure.
*/
if (!test_bit(HCI_CONN_MASTER, &hcon->flags) &&
(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;
req.min = cpu_to_le16(hcon->le_conn_min_interval);
req.max = cpu_to_le16(hcon->le_conn_max_interval);
req.latency = cpu_to_le16(hcon->le_conn_latency);
req.to_multiplier = cpu_to_le16(hcon->le_supv_timeout);
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req);
}
l2cap_chan_lock(pchan);
chan = pchan->ops->new_connection(pchan);
......@@ -2118,7 +2141,8 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
struct sk_buff **frag;
int sent = 0;
if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
if (chan->ops->memcpy_fromiovec(chan, skb_put(skb, count),
msg->msg_iov, count))
return -EFAULT;
sent += count;
......@@ -2131,18 +2155,17 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
count = min_t(unsigned int, conn->mtu, len);
tmp = chan->ops->alloc_skb(chan, count,
tmp = chan->ops->alloc_skb(chan, 0, count,
msg->msg_flags & MSG_DONTWAIT);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
*frag = tmp;
if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
if (chan->ops->memcpy_fromiovec(chan, skb_put(*frag, count),
msg->msg_iov, count))
return -EFAULT;
(*frag)->priority = skb->priority;
sent += count;
len -= count;
......@@ -2156,26 +2179,23 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
}
static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
struct msghdr *msg, size_t len)
{
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
struct l2cap_hdr *lh;
BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
__le16_to_cpu(chan->psm), len, priority);
BT_DBG("chan %p psm 0x%2.2x len %zu", chan,
__le16_to_cpu(chan->psm), len);
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = chan->ops->alloc_skb(chan, count + hlen,
skb = chan->ops->alloc_skb(chan, hlen, count,
msg->msg_flags & MSG_DONTWAIT);
if (IS_ERR(skb))
return skb;
skb->priority = priority;
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(chan->dcid);
......@@ -2191,8 +2211,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
}
static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
struct msghdr *msg, size_t len)
{
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
......@@ -2203,13 +2222,11 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
skb = chan->ops->alloc_skb(chan, L2CAP_HDR_SIZE, count,
msg->msg_flags & MSG_DONTWAIT);
if (IS_ERR(skb))
return skb;
skb->priority = priority;
/* Create L2CAP header */
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(chan->dcid);
......@@ -2247,7 +2264,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = chan->ops->alloc_skb(chan, count + hlen,
skb = chan->ops->alloc_skb(chan, hlen, count,
msg->msg_flags & MSG_DONTWAIT);
if (IS_ERR(skb))
return skb;
......@@ -2368,7 +2385,7 @@ static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = chan->ops->alloc_skb(chan, count + hlen,
skb = chan->ops->alloc_skb(chan, hlen, count,
msg->msg_flags & MSG_DONTWAIT);
if (IS_ERR(skb))
return skb;
......@@ -2430,8 +2447,7 @@ static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
return 0;
}
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
u32 priority)
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{
struct sk_buff *skb;
int err;
......@@ -2442,7 +2458,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
/* Connectionless channel */
if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
skb = l2cap_create_connless_pdu(chan, msg, len, priority);
skb = l2cap_create_connless_pdu(chan, msg, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
......@@ -2499,7 +2515,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
return -EMSGSIZE;
/* Create a basic PDU */
skb = l2cap_create_basic_pdu(chan, msg, len, priority);
skb = l2cap_create_basic_pdu(chan, msg, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
......@@ -2562,6 +2578,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
return err;
}
EXPORT_SYMBOL_GPL(l2cap_chan_send);
static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
{
......@@ -3217,6 +3234,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
switch (chan->mode) {
case L2CAP_MODE_BASIC:
if (disable_ertm)
break;
if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
!(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
break;
......@@ -5197,27 +5217,6 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
return 0;
}
static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
u16 to_multiplier)
{
u16 max_latency;
if (min > max || min < 6 || max > 3200)
return -EINVAL;
if (to_multiplier < 10 || to_multiplier > 3200)
return -EINVAL;
if (max >= to_multiplier * 8)
return -EINVAL;
max_latency = (to_multiplier * 8 / max) - 1;
if (latency > 499 || latency > max_latency)
return -EINVAL;
return 0;
}
static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd,
u16 cmd_len, u8 *data)
......@@ -5228,7 +5227,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
u16 min, max, latency, to_multiplier;
int err;
if (!(hcon->link_mode & HCI_LM_MASTER))
if (!test_bit(HCI_CONN_MASTER, &hcon->flags))
return -EINVAL;
if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
......@@ -5245,7 +5244,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
memset(&rsp, 0, sizeof(rsp));
err = l2cap_check_conn_param(min, max, latency, to_multiplier);
err = hci_check_conn_params(min, max, latency, to_multiplier);
if (err)
rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
else
......@@ -5254,8 +5253,16 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
sizeof(rsp), &rsp);
if (!err)
hci_le_conn_update(hcon, min, max, latency, to_multiplier);
if (!err) {
u8 store_hint;
store_hint = hci_le_conn_update(hcon, min, max, latency,
to_multiplier);
mgmt_new_conn_param(hcon->hdev, &hcon->dst, hcon->dst_type,
store_hint, min, max, latency,
to_multiplier);
}
return 0;
}
......@@ -6879,9 +6886,6 @@ static void l2cap_att_channel(struct l2cap_conn *conn,
BT_DBG("chan %p, len %d", chan, skb->len);
if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, hcon->dst_type))
goto drop;
if (chan->imtu < skb->len)
goto drop;
......@@ -6914,6 +6918,16 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
return;
}
/* Since we can't actively block incoming LE connections we must
* at least ensure that we ignore incoming data from them.
*/
if (hcon->type == LE_LINK &&
hci_bdaddr_list_lookup(&hcon->hdev->blacklist, &hcon->dst,
bdaddr_type(hcon, hcon->dst_type))) {
kfree_skb(skb);
return;
}
BT_DBG("len %d, cid 0x%4.4x", len, cid);
switch (cid) {
......@@ -6940,10 +6954,6 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_conn_del(conn->hcon, EACCES);
break;
case L2CAP_FC_6LOWPAN:
bt_6lowpan_recv(conn, skb);
break;
default:
l2cap_data_channel(conn, cid, skb);
break;
......@@ -7042,7 +7052,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
__u8 auth_type;
int err;
BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
......@@ -7118,9 +7127,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
chan->psm = psm;
chan->dcid = cid;
auth_type = l2cap_get_auth_type(chan);
if (bdaddr_type_is_le(dst_type)) {
bool master;
/* Convert from L2CAP channel address type to HCI address type
*/
if (dst_type == BDADDR_LE_PUBLIC)
......@@ -7128,9 +7137,12 @@ 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);
hcon = hci_connect_le(hdev, dst, dst_type, chan->sec_level,
auth_type);
HCI_LE_CONN_TIMEOUT, master);
} else {
u8 auth_type = l2cap_get_auth_type(chan);
hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
}
......@@ -7190,6 +7202,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
hci_dev_put(hdev);
return err;
}
EXPORT_SYMBOL_GPL(l2cap_chan_connect);
/* ---- L2CAP interface with lower layer (HCI) ---- */
......@@ -7252,8 +7265,6 @@ void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
{
BT_DBG("hcon %p reason %d", hcon, reason);
bt_6lowpan_del_conn(hcon->l2cap_data);
l2cap_conn_del(hcon, bt_to_errno(reason));
}
......@@ -7536,14 +7547,11 @@ int __init l2cap_init(void)
debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
&le_default_mps);
bt_6lowpan_init();
return 0;
}
void l2cap_exit(void)
{
bt_6lowpan_cleanup();
debugfs_remove(l2cap_debugfs);
l2cap_cleanup_sockets();
}
......
......@@ -361,7 +361,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
BT_DBG("sock %p, sk %p", sock, sk);
if (peer && sk->sk_state != BT_CONNECTED &&
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 &&
sk->sk_state != BT_CONFIG)
return -ENOTCONN;
memset(la, 0, sizeof(struct sockaddr_l2));
......@@ -964,7 +965,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return err;
l2cap_chan_lock(chan);
err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
err = l2cap_chan_send(chan, msg, len);
l2cap_chan_unlock(chan);
return err;
......@@ -1292,6 +1293,7 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
}
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb)
{
struct sock *sk = chan->data;
......@@ -1299,17 +1301,26 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
int err;
l2cap_chan_unlock(chan);
skb = bt_skb_send_alloc(sk, len, nb, &err);
skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);
l2cap_chan_lock(chan);
if (!skb)
return ERR_PTR(err);
skb->priority = sk->sk_priority;
bt_cb(skb)->chan = chan;
return skb;
}
static int l2cap_sock_memcpy_fromiovec_cb(struct l2cap_chan *chan,
unsigned char *kdata,
struct iovec *iov, int len)
{
return memcpy_fromiovec(kdata, iov, len);
}
static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
......@@ -1375,7 +1386,7 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
sk->sk_state_change(sk);
}
static struct l2cap_ops l2cap_chan_ops = {
static const struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
.recv = l2cap_sock_recv_cb,
......@@ -1389,6 +1400,7 @@ static struct l2cap_ops l2cap_chan_ops = {
.set_shutdown = l2cap_sock_set_shutdown_cb,
.get_sndtimeo = l2cap_sock_get_sndtimeo_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb,
.memcpy_fromiovec = l2cap_sock_memcpy_fromiovec_cb,
};
static void l2cap_sock_destruct(struct sock *sk)
......
......@@ -35,7 +35,7 @@
#include "smp.h"
#define MGMT_VERSION 1
#define MGMT_REVISION 6
#define MGMT_REVISION 7
static const u16 mgmt_commands[] = {
MGMT_OP_READ_INDEX_LIST,
......@@ -85,6 +85,14 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_PRIVACY,
MGMT_OP_LOAD_IRKS,
MGMT_OP_GET_CONN_INFO,
MGMT_OP_GET_CLOCK_INFO,
MGMT_OP_ADD_DEVICE,
MGMT_OP_REMOVE_DEVICE,
MGMT_OP_LOAD_CONN_PARAM,
MGMT_OP_READ_UNCONF_INDEX_LIST,
MGMT_OP_READ_CONFIG_INFO,
MGMT_OP_SET_EXTERNAL_CONFIG,
MGMT_OP_SET_PUBLIC_ADDRESS,
};
static const u16 mgmt_events[] = {
......@@ -111,6 +119,12 @@ static const u16 mgmt_events[] = {
MGMT_EV_PASSKEY_NOTIFY,
MGMT_EV_NEW_IRK,
MGMT_EV_NEW_CSRK,
MGMT_EV_DEVICE_ADDED,
MGMT_EV_DEVICE_REMOVED,
MGMT_EV_NEW_CONN_PARAM,
MGMT_EV_UNCONF_INDEX_ADDED,
MGMT_EV_UNCONF_INDEX_REMOVED,
MGMT_EV_NEW_CONFIG_OPTIONS,
};
#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
......@@ -200,6 +214,36 @@ 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)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = cpu_to_le16(event);
if (hdev)
hdr->index = cpu_to_le16(hdev->id);
else
hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
hdr->len = cpu_to_le16(data_len);
if (data)
memcpy(skb_put(skb, data_len), data, data_len);
/* Time stamp */
__net_timestamp(skb);
hci_send_to_control(skb, skip_sk);
kfree_skb(skb);
return 0;
}
static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
{
struct sk_buff *skb;
......@@ -327,7 +371,8 @@ 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)
if (d->dev_type == HCI_BREDR &&
!test_bit(HCI_UNCONFIGURED, &d->dev_flags))
count++;
}
......@@ -340,13 +385,19 @@ 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))
if (test_bit(HCI_SETUP, &d->dev_flags) ||
test_bit(HCI_CONFIG, &d->dev_flags) ||
test_bit(HCI_USER_CHANNEL, &d->dev_flags))
continue;
if (test_bit(HCI_USER_CHANNEL, &d->dev_flags))
/* Devices marked as raw-only are neither configured
* nor unconfigured controllers.
*/
if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
continue;
if (d->dev_type == HCI_BREDR) {
if (d->dev_type == HCI_BREDR &&
!test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
rp->index[count++] = cpu_to_le16(d->id);
BT_DBG("Added hci%u", d->id);
}
......@@ -365,6 +416,138 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
return err;
}
static int read_unconf_index_list(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len)
{
struct mgmt_rp_read_unconf_index_list *rp;
struct hci_dev *d;
size_t rp_len;
u16 count;
int err;
BT_DBG("sock %p", sk);
read_lock(&hci_dev_list_lock);
count = 0;
list_for_each_entry(d, &hci_dev_list, list) {
if (d->dev_type == HCI_BREDR &&
test_bit(HCI_UNCONFIGURED, &d->dev_flags))
count++;
}
rp_len = sizeof(*rp) + (2 * count);
rp = kmalloc(rp_len, GFP_ATOMIC);
if (!rp) {
read_unlock(&hci_dev_list_lock);
return -ENOMEM;
}
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))
continue;
/* Devices marked as raw-only are neither configured
* nor unconfigured controllers.
*/
if (test_bit(HCI_QUIRK_RAW_DEVICE, &d->quirks))
continue;
if (d->dev_type == HCI_BREDR &&
test_bit(HCI_UNCONFIGURED, &d->dev_flags)) {
rp->index[count++] = cpu_to_le16(d->id);
BT_DBG("Added hci%u", d->id);
}
}
rp->num_controllers = cpu_to_le16(count);
rp_len = sizeof(*rp) + (2 * count);
read_unlock(&hci_dev_list_lock);
err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_UNCONF_INDEX_LIST,
0, rp, rp_len);
kfree(rp);
return err;
}
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))
return false;
if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
!bacmp(&hdev->public_addr, BDADDR_ANY))
return false;
return true;
}
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))
options |= MGMT_OPTION_EXTERNAL_CONFIG;
if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
!bacmp(&hdev->public_addr, BDADDR_ANY))
options |= MGMT_OPTION_PUBLIC_ADDRESS;
return cpu_to_le32(options);
}
static int new_options(struct hci_dev *hdev, struct sock *skip)
{
__le32 options = get_missing_options(hdev);
return mgmt_event(MGMT_EV_NEW_CONFIG_OPTIONS, hdev, &options,
sizeof(options), skip);
}
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));
}
static int read_config_info(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len)
{
struct mgmt_rp_read_config_info rp;
u32 options = 0;
BT_DBG("sock %p %s", sk, hdev->name);
hci_dev_lock(hdev);
memset(&rp, 0, sizeof(rp));
rp.manufacturer = cpu_to_le16(hdev->manufacturer);
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
options |= MGMT_OPTION_EXTERNAL_CONFIG;
if (hdev->set_bdaddr)
options |= MGMT_OPTION_PUBLIC_ADDRESS;
rp.supported_options = cpu_to_le32(options);
rp.missing_options = get_missing_options(hdev);
hci_dev_unlock(hdev);
return cmd_complete(sk, hdev->id, MGMT_OP_READ_CONFIG_INFO, 0, &rp,
sizeof(rp));
}
static u32 get_supported_settings(struct hci_dev *hdev)
{
u32 settings = 0;
......@@ -372,12 +555,12 @@ static u32 get_supported_settings(struct hci_dev *hdev)
settings |= MGMT_SETTING_POWERED;
settings |= MGMT_SETTING_PAIRABLE;
settings |= MGMT_SETTING_DEBUG_KEYS;
settings |= MGMT_SETTING_CONNECTABLE;
settings |= MGMT_SETTING_DISCOVERABLE;
if (lmp_bredr_capable(hdev)) {
settings |= MGMT_SETTING_CONNECTABLE;
if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
settings |= MGMT_SETTING_FAST_CONNECTABLE;
settings |= MGMT_SETTING_DISCOVERABLE;
settings |= MGMT_SETTING_BREDR;
settings |= MGMT_SETTING_LINK_SECURITY;
......@@ -387,7 +570,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
}
if (lmp_sc_capable(hdev) ||
test_bit(HCI_FORCE_SC, &hdev->dev_flags))
test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
settings |= MGMT_SETTING_SECURE_CONN;
}
......@@ -397,6 +580,10 @@ static u32 get_supported_settings(struct hci_dev *hdev)
settings |= MGMT_SETTING_PRIVACY;
}
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
hdev->set_bdaddr)
settings |= MGMT_SETTING_CONFIGURATION;
return settings;
}
......@@ -440,7 +627,7 @@ static u32 get_current_settings(struct hci_dev *hdev)
if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags))
settings |= MGMT_SETTING_SECURE_CONN;
if (test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags))
if (test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags))
settings |= MGMT_SETTING_DEBUG_KEYS;
if (test_bit(HCI_PRIVACY, &hdev->dev_flags))
......@@ -571,6 +758,22 @@ 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)
{
struct pending_cmd *cmd;
list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
if (cmd->user_data != data)
continue;
if (cmd->opcode == opcode)
return cmd;
}
return NULL;
}
static u8 create_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
{
u8 ad_len = 0;
......@@ -836,6 +1039,13 @@ static bool get_connectable(struct hci_dev *hdev)
return test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
}
static void disable_advertising(struct hci_request *req)
{
u8 enable = 0x00;
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
}
static void enable_advertising(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
......@@ -843,12 +1053,18 @@ static void enable_advertising(struct hci_request *req)
u8 own_addr_type, enable = 0x01;
bool connectable;
/* Clear the HCI_ADVERTISING bit temporarily so that the
if (hci_conn_num(hdev, LE_LINK) > 0)
return;
if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
disable_advertising(req);
/* Clear the HCI_LE_ADV bit temporarily so that the
* hci_update_random_address knows that it's safe to go ahead
* 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_ADVERTISING, &hdev->dev_flags);
clear_bit(HCI_LE_ADV, &hdev->dev_flags);
connectable = get_connectable(hdev);
......@@ -871,13 +1087,6 @@ static void enable_advertising(struct hci_request *req)
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
}
static void disable_advertising(struct hci_request *req)
{
u8 enable = 0x00;
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
}
static void service_cache_off(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
......@@ -909,19 +1118,14 @@ static void rpa_expired(struct work_struct *work)
set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags) ||
hci_conn_num(hdev, LE_LINK) > 0)
if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
return;
/* The generation of a new RPA and programming it into the
* controller happens in the enable_advertising() function.
*/
hci_req_init(&req, hdev);
disable_advertising(&req);
enable_advertising(&req);
hci_req_run(&req, NULL);
}
......@@ -984,7 +1188,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
{
struct pending_cmd *cmd;
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd)
return NULL;
......@@ -1047,7 +1251,7 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
}
}
static void hci_stop_discovery(struct hci_request *req)
static bool hci_stop_discovery(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
struct hci_cp_remote_name_req_cancel cp;
......@@ -1062,32 +1266,39 @@ static void hci_stop_discovery(struct hci_request *req)
hci_req_add_le_scan_disable(req);
}
break;
return true;
case DISCOVERY_RESOLVING:
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
NAME_PENDING);
if (!e)
return;
break;
bacpy(&cp.bdaddr, &e->data.bdaddr);
hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
&cp);
break;
return true;
default:
/* Passive scanning */
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
hci_req_add_le_scan_disable(req);
return true;
}
break;
}
return false;
}
static int clean_up_hci_state(struct hci_dev *hdev)
{
struct hci_request req;
struct hci_conn *conn;
bool discov_stopped;
int err;
hci_req_init(&req, hdev);
......@@ -1097,10 +1308,10 @@ 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_ADVERTISING, &hdev->dev_flags))
if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
disable_advertising(&req);
hci_stop_discovery(&req);
discov_stopped = hci_stop_discovery(&req);
list_for_each_entry(conn, &hdev->conn_hash.list, list) {
struct hci_cp_disconnect dc;
......@@ -1134,7 +1345,11 @@ static int clean_up_hci_state(struct hci_dev *hdev)
}
}
return hci_req_run(&req, clean_up_hci_complete);
err = hci_req_run(&req, clean_up_hci_complete);
if (!err && discov_stopped)
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
return err;
}
static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
......@@ -1203,36 +1418,6 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
return err;
}
static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
struct sock *skip_sk)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = cpu_to_le16(event);
if (hdev)
hdr->index = cpu_to_le16(hdev->id);
else
hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
hdr->len = cpu_to_le16(data_len);
if (data)
memcpy(skb_put(skb, data_len), data, data_len);
/* Time stamp */
__net_timestamp(skb);
hci_send_to_control(skb, skip_sk);
kfree_skb(skb);
return 0;
}
static int new_settings(struct hci_dev *hdev, struct sock *skip)
{
__le32 ev;
......@@ -1242,6 +1427,11 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
}
int mgmt_new_settings(struct hci_dev *hdev)
{
return new_settings(hdev, NULL);
}
struct cmd_lookup {
struct sock *sk;
struct hci_dev *hdev;
......@@ -1577,8 +1767,10 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status)
send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
if (changed)
if (changed) {
new_settings(hdev, cmd->sk);
hci_update_background_scan(hdev);
}
remove_cmd:
mgmt_pending_remove(cmd);
......@@ -1607,8 +1799,10 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
if (err < 0)
return err;
if (changed)
if (changed) {
hci_update_background_scan(hdev);
return new_settings(hdev, sk);
}
return 0;
}
......@@ -1689,10 +1883,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
write_fast_connectable(&req, false);
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) &&
hci_conn_num(hdev, LE_LINK) == 0) {
disable_advertising(&req);
!test_bit(HCI_LE_ADV, &hdev->dev_flags))
enable_advertising(&req);
}
err = hci_req_run(&req, set_connectable_complete);
if (err < 0) {
......@@ -1877,6 +2069,10 @@ 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))
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(cp->val), &cp->val);
err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &cp->val);
if (err < 0) {
mgmt_pending_remove(cmd);
......@@ -1973,6 +2169,8 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
update_scan_rsp_data(&req);
hci_req_run(&req, NULL);
hci_update_background_scan(hdev);
hci_dev_unlock(hdev);
}
}
......@@ -2050,7 +2248,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
hci_cp.le = val;
hci_cp.simul = lmp_le_br_capable(hdev);
} else {
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
disable_advertising(&req);
}
......@@ -2373,6 +2571,8 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
struct mgmt_cp_load_link_keys *cp = data;
const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
sizeof(struct mgmt_link_key_info));
u16 key_count, expected_len;
bool changed;
int i;
......@@ -2384,6 +2584,12 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
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);
}
expected_len = sizeof(*cp) + key_count *
sizeof(struct mgmt_link_key_info);
......@@ -2414,9 +2620,11 @@ 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_DEBUG_KEYS, &hdev->dev_flags);
changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
&hdev->dev_flags);
else
changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
&hdev->dev_flags);
if (changed)
new_settings(hdev, NULL);
......@@ -2424,8 +2632,14 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
for (i = 0; i < key_count; i++) {
struct mgmt_link_key_info *key = &cp->keys[i];
hci_add_link_key(hdev, NULL, 0, &key->addr.bdaddr, key->val,
key->type, key->pin_len);
/* Always ignore debug keys and require a new pairing if
* the user wants to use them.
*/
if (key->type == HCI_LK_DEBUG_COMBINATION)
continue;
hci_add_link_key(hdev, NULL, &key->addr.bdaddr, key->val,
key->type, key->pin_len, NULL);
}
cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
......@@ -2766,6 +2980,10 @@ 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);
hci_dev_lock(hdev);
hdev->io_capability = cp->io_capability;
......@@ -2878,6 +3096,11 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
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));
hci_dev_lock(hdev);
if (!hdev_is_powered(hdev)) {
......@@ -2902,8 +3125,20 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
else
addr_type = ADDR_LE_DEV_RANDOM;
/* When pairing a new device, it is expected to remember
* this device for future connections. Adding the connection
* parameter information ahead of time allows tracking
* of the slave preferred values and will speed up any
* further connection establishment.
*
* If connection parameters already exist, then they
* will be kept and this function does nothing.
*/
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, auth_type);
sec_level, HCI_LE_CONN_TIMEOUT, true);
}
if (IS_ERR(conn)) {
......@@ -3031,14 +3266,7 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
}
if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
/* Continue with pairing via SMP. The hdev lock must be
* released as SMP may try to recquire it for crypto
* purposes.
*/
hci_dev_unlock(hdev);
err = smp_user_confirm_reply(conn, mgmt_op, passkey);
hci_dev_lock(hdev);
if (!err)
err = cmd_complete(sk, hdev->id, mgmt_op,
MGMT_STATUS_SUCCESS, addr,
......@@ -3516,13 +3744,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
goto failed;
}
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
/* Don't let discovery abort an outgoing
* connection attempt that's using directed
* advertising.
*/
if (hci_conn_hash_lookup_state(hdev, LE_LINK,
BT_CONNECT)) {
err = cmd_status(sk, hdev->id,
MGMT_OP_START_DISCOVERY,
MGMT_STATUS_REJECTED);
mgmt_pending_remove(cmd);
goto failed;
}
disable_advertising(&req);
}
/* If controller is scanning, it means the background scanning
* is running. Thus, we should temporarily stop it in order to
* set the discovery scanning parameters.
......@@ -3723,12 +3961,18 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
hci_dev_lock(hdev);
err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
if (err < 0)
err = hci_bdaddr_list_add(&hdev->blacklist, &cp->addr.bdaddr,
cp->addr.type);
if (err < 0) {
status = MGMT_STATUS_FAILED;
else
goto done;
}
mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &cp->addr, sizeof(cp->addr),
sk);
status = MGMT_STATUS_SUCCESS;
done:
err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
&cp->addr, sizeof(cp->addr));
......@@ -3753,12 +3997,18 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
hci_dev_lock(hdev);
err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
if (err < 0)
err = hci_bdaddr_list_del(&hdev->blacklist, &cp->addr.bdaddr,
cp->addr.type);
if (err < 0) {
status = MGMT_STATUS_INVALID_PARAMS;
else
goto done;
}
mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &cp->addr, sizeof(cp->addr),
sk);
status = MGMT_STATUS_SUCCESS;
done:
err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
&cp->addr, sizeof(cp->addr));
......@@ -3813,6 +4063,11 @@ static void set_advertising_complete(struct hci_dev *hdev, u8 status)
return;
}
if (test_bit(HCI_LE_ADV, &hdev->dev_flags))
set_bit(HCI_ADVERTISING, &hdev->dev_flags);
else
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
&match);
......@@ -3853,7 +4108,9 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
* necessary).
*/
if (!hdev_is_powered(hdev) || val == enabled ||
hci_conn_num(hdev, LE_LINK) > 0) {
hci_conn_num(hdev, LE_LINK) > 0 ||
(test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
hdev->le_scan_type == LE_SCAN_ACTIVE)) {
bool changed = false;
if (val != test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
......@@ -4105,7 +4362,8 @@ static void set_bredr_scan(struct hci_request *req)
*/
write_fast_connectable(req, false);
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
!list_empty(&hdev->whitelist))
scan |= SCAN_PAGE;
if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
scan |= SCAN_INQUIRY;
......@@ -4219,7 +4477,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
hci_req_init(&req, hdev);
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
!list_empty(&hdev->whitelist))
set_bredr_scan(&req);
/* Since only the advertising data flags will change, there
......@@ -4252,7 +4511,7 @@ static int set_secure_conn(struct sock *sk, struct hci_dev *hdev,
status);
if (!lmp_sc_capable(hdev) &&
!test_bit(HCI_FORCE_SC, &hdev->dev_flags))
!test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
return cmd_status(sk, hdev->id, MGMT_OP_SET_SECURE_CONN,
MGMT_STATUS_NOT_SUPPORTED);
......@@ -4328,21 +4587,37 @@ static int set_debug_keys(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_mode *cp = data;
bool changed;
bool changed, use_changed;
int err;
BT_DBG("request for %s", hdev->name);
if (cp->val != 0x00 && cp->val != 0x01)
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);
hci_dev_lock(hdev);
if (cp->val)
changed = !test_and_set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
changed = !test_and_set_bit(HCI_KEEP_DEBUG_KEYS,
&hdev->dev_flags);
else
changed = test_and_clear_bit(HCI_KEEP_DEBUG_KEYS,
&hdev->dev_flags);
if (cp->val == 0x02)
use_changed = !test_and_set_bit(HCI_USE_DEBUG_KEYS,
&hdev->dev_flags);
else
changed = test_and_clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
use_changed = test_and_clear_bit(HCI_USE_DEBUG_KEYS,
&hdev->dev_flags);
if (hdev_is_powered(hdev) && use_changed &&
test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
u8 mode = (cp->val == 0x02) ? 0x01 : 0x00;
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(mode), &mode);
}
err = send_settings_rsp(sk, MGMT_OP_SET_DEBUG_KEYS, hdev);
if (err < 0)
......@@ -4426,6 +4701,8 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
u16 len)
{
struct mgmt_cp_load_irks *cp = cp_data;
const u16 max_irk_count = ((U16_MAX - sizeof(*cp)) /
sizeof(struct mgmt_irk_info));
u16 irk_count, expected_len;
int i, err;
......@@ -4436,6 +4713,11 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
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);
}
expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
if (expected_len != len) {
......@@ -4505,6 +4787,8 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
void *cp_data, u16 len)
{
struct mgmt_cp_load_long_term_keys *cp = cp_data;
const u16 max_key_count = ((U16_MAX - sizeof(*cp)) /
sizeof(struct mgmt_ltk_info));
u16 key_count, expected_len;
int i, err;
......@@ -4515,6 +4799,11 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
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);
}
expected_len = sizeof(*cp) + key_count *
sizeof(struct mgmt_ltk_info);
......@@ -4550,9 +4839,9 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
addr_type = ADDR_LE_DEV_RANDOM;
if (key->master)
type = HCI_SMP_LTK;
type = SMP_LTK;
else
type = HCI_SMP_LTK_SLAVE;
type = SMP_LTK_SLAVE;
switch (key->type) {
case MGMT_LTK_UNAUTHENTICATED:
......@@ -4790,6 +5079,559 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
return err;
}
static void get_clock_info_complete(struct hci_dev *hdev, u8 status)
{
struct mgmt_cp_get_clock_info *cp;
struct mgmt_rp_get_clock_info rp;
struct hci_cp_read_clock *hci_cp;
struct pending_cmd *cmd;
struct hci_conn *conn;
BT_DBG("%s status %u", hdev->name, status);
hci_dev_lock(hdev);
hci_cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
if (!hci_cp)
goto unlock;
if (hci_cp->which) {
u16 handle = __le16_to_cpu(hci_cp->handle);
conn = hci_conn_hash_lookup_handle(hdev, handle);
} else {
conn = NULL;
}
cmd = mgmt_pending_find_data(MGMT_OP_GET_CLOCK_INFO, hdev, conn);
if (!cmd)
goto unlock;
cp = cmd->param;
memset(&rp, 0, sizeof(rp));
memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
if (status)
goto send_rsp;
rp.local_clock = cpu_to_le32(hdev->clock);
if (conn) {
rp.piconet_clock = cpu_to_le32(conn->clock);
rp.accuracy = cpu_to_le16(conn->clock_accuracy);
}
send_rsp:
cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
&rp, sizeof(rp));
mgmt_pending_remove(cmd);
if (conn)
hci_conn_drop(conn);
unlock:
hci_dev_unlock(hdev);
}
static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
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 hci_request req;
struct hci_conn *conn;
int err;
BT_DBG("%s", hdev->name);
memset(&rp, 0, sizeof(rp));
bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
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));
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));
goto unlock;
}
if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
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));
goto unlock;
}
} else {
conn = NULL;
}
cmd = mgmt_pending_add(sk, MGMT_OP_GET_CLOCK_INFO, hdev, data, len);
if (!cmd) {
err = -ENOMEM;
goto unlock;
}
hci_req_init(&req, hdev);
memset(&hci_cp, 0, sizeof(hci_cp));
hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
if (conn) {
hci_conn_hold(conn);
cmd->user_data = conn;
hci_cp.handle = cpu_to_le16(conn->handle);
hci_cp.which = 0x01; /* Piconet clock */
hci_req_add(&req, HCI_OP_READ_CLOCK, sizeof(hci_cp), &hci_cp);
}
err = hci_req_run(&req, get_clock_info_complete);
if (err < 0)
mgmt_pending_remove(cmd);
unlock:
hci_dev_unlock(hdev);
return err;
}
/* Helper for Add/Remove Device commands */
static void update_page_scan(struct hci_dev *hdev, u8 scan)
{
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
return;
if (!hdev_is_powered(hdev))
return;
/* If HCI_CONNECTABLE is set then Add/Remove Device should not
* make any changes to page scanning.
*/
if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
return;
if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
scan |= SCAN_INQUIRY;
hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
}
static void device_added(struct sock *sk, struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type, u8 action)
{
struct mgmt_ev_device_added ev;
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = type;
ev.action = action;
mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
}
static int add_device(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_add_device *cp = data;
u8 auto_conn, addr_type;
int err;
BT_DBG("%s", hdev->name);
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));
if (cp->action != 0x00 && cp->action != 0x01)
return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
hci_dev_lock(hdev);
if (cp->addr.type == BDADDR_BREDR) {
bool update_scan;
/* Only "connect" action supported for now */
if (cp->action != 0x01) {
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
update_scan = list_empty(&hdev->whitelist);
err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
cp->addr.type);
if (err)
goto unlock;
if (update_scan)
update_page_scan(hdev, SCAN_PAGE);
goto added;
}
if (cp->addr.type == BDADDR_LE_PUBLIC)
addr_type = ADDR_LE_DEV_PUBLIC;
else
addr_type = ADDR_LE_DEV_RANDOM;
if (cp->action)
auto_conn = HCI_AUTO_CONN_ALWAYS;
else
auto_conn = HCI_AUTO_CONN_REPORT;
/* If the connection parameters don't exist for this device,
* they will be created and configured with defaults.
*/
if (hci_conn_params_set(hdev, &cp->addr.bdaddr, addr_type,
auto_conn) < 0) {
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_FAILED,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
added:
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr));
unlock:
hci_dev_unlock(hdev);
return err;
}
static void device_removed(struct sock *sk, struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type)
{
struct mgmt_ev_device_removed ev;
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = type;
mgmt_event(MGMT_EV_DEVICE_REMOVED, hdev, &ev, sizeof(ev), sk);
}
static int remove_device(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_remove_device *cp = data;
int err;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
if (bacmp(&cp->addr.bdaddr, BDADDR_ANY)) {
struct hci_conn_params *params;
u8 addr_type;
if (!bdaddr_type_is_valid(cp->addr.type)) {
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
if (cp->addr.type == BDADDR_BREDR) {
err = hci_bdaddr_list_del(&hdev->whitelist,
&cp->addr.bdaddr,
cp->addr.type);
if (err) {
err = cmd_complete(sk, hdev->id,
MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
if (list_empty(&hdev->whitelist))
update_page_scan(hdev, SCAN_DISABLED);
device_removed(sk, hdev, &cp->addr.bdaddr,
cp->addr.type);
goto complete;
}
if (cp->addr.type == BDADDR_LE_PUBLIC)
addr_type = ADDR_LE_DEV_PUBLIC;
else
addr_type = ADDR_LE_DEV_RANDOM;
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
addr_type);
if (!params) {
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
if (params->auto_connect == HCI_AUTO_CONN_DISABLED) {
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
list_del(&params->action);
list_del(&params->list);
kfree(params);
hci_update_background_scan(hdev);
device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type);
} else {
struct hci_conn_params *p, *tmp;
struct bdaddr_list *b, *btmp;
if (cp->addr.type) {
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_INVALID_PARAMS,
&cp->addr, sizeof(cp->addr));
goto unlock;
}
list_for_each_entry_safe(b, btmp, &hdev->whitelist, list) {
device_removed(sk, hdev, &b->bdaddr, b->bdaddr_type);
list_del(&b->list);
kfree(b);
}
update_page_scan(hdev, SCAN_DISABLED);
list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) {
if (p->auto_connect == HCI_AUTO_CONN_DISABLED)
continue;
device_removed(sk, hdev, &p->addr, p->addr_type);
list_del(&p->action);
list_del(&p->list);
kfree(p);
}
BT_DBG("All LE connection parameters were removed");
hci_update_background_scan(hdev);
}
complete:
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_DEVICE,
MGMT_STATUS_SUCCESS, &cp->addr, sizeof(cp->addr));
unlock:
hci_dev_unlock(hdev);
return err;
}
static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
struct mgmt_cp_load_conn_param *cp = data;
const u16 max_param_count = ((U16_MAX - sizeof(*cp)) /
sizeof(struct mgmt_conn_param));
u16 param_count, expected_len;
int i;
if (!lmp_le_capable(hdev))
return 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);
}
expected_len = sizeof(*cp) + param_count *
sizeof(struct mgmt_conn_param);
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);
}
BT_DBG("%s param_count %u", hdev->name, param_count);
hci_dev_lock(hdev);
hci_conn_params_clear_disabled(hdev);
for (i = 0; i < param_count; i++) {
struct mgmt_conn_param *param = &cp->params[i];
struct hci_conn_params *hci_param;
u16 min, max, latency, timeout;
u8 addr_type;
BT_DBG("Adding %pMR (type %u)", &param->addr.bdaddr,
param->addr.type);
if (param->addr.type == BDADDR_LE_PUBLIC) {
addr_type = ADDR_LE_DEV_PUBLIC;
} else if (param->addr.type == BDADDR_LE_RANDOM) {
addr_type = ADDR_LE_DEV_RANDOM;
} else {
BT_ERR("Ignoring invalid connection parameters");
continue;
}
min = le16_to_cpu(param->min_interval);
max = le16_to_cpu(param->max_interval);
latency = le16_to_cpu(param->latency);
timeout = le16_to_cpu(param->timeout);
BT_DBG("min 0x%04x max 0x%04x latency 0x%04x timeout 0x%04x",
min, max, latency, timeout);
if (hci_check_conn_params(min, max, latency, timeout) < 0) {
BT_ERR("Ignoring invalid connection parameters");
continue;
}
hci_param = hci_conn_params_add(hdev, &param->addr.bdaddr,
addr_type);
if (!hci_param) {
BT_ERR("Failed to add connection parameters");
continue;
}
hci_param->conn_min_interval = min;
hci_param->conn_max_interval = max;
hci_param->conn_latency = latency;
hci_param->supervision_timeout = timeout;
}
hci_dev_unlock(hdev);
return 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,
void *data, u16 len)
{
struct mgmt_cp_set_external_config *cp = data;
bool changed;
int err;
BT_DBG("%s", hdev->name);
if (hdev_is_powered(hdev))
return 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);
if (!test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks))
return 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);
else
changed = test_and_clear_bit(HCI_EXT_CONFIGURED,
&hdev->dev_flags);
err = send_options_rsp(sk, MGMT_OP_SET_EXTERNAL_CONFIG, hdev);
if (err < 0)
goto unlock;
if (!changed)
goto unlock;
err = new_options(hdev, sk);
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) == 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);
queue_work(hdev->req_workqueue, &hdev->power_on);
} else {
set_bit(HCI_RAW, &hdev->flags);
mgmt_index_added(hdev);
}
}
unlock:
hci_dev_unlock(hdev);
return err;
}
static int set_public_address(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_set_public_address *cp = data;
bool changed;
int err;
BT_DBG("%s", hdev->name);
if (hdev_is_powered(hdev))
return 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);
if (!hdev->set_bdaddr)
return cmd_status(sk, hdev->id, MGMT_OP_SET_PUBLIC_ADDRESS,
MGMT_STATUS_NOT_SUPPORTED);
hci_dev_lock(hdev);
changed = !!bacmp(&hdev->public_addr, &cp->bdaddr);
bacpy(&hdev->public_addr, &cp->bdaddr);
err = send_options_rsp(sk, MGMT_OP_SET_PUBLIC_ADDRESS, hdev);
if (err < 0)
goto unlock;
if (!changed)
goto unlock;
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
err = new_options(hdev, sk);
if (is_configured(hdev)) {
mgmt_index_removed(hdev);
clear_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
set_bit(HCI_CONFIG, &hdev->dev_flags);
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
queue_work(hdev->req_workqueue, &hdev->power_on);
}
unlock:
hci_dev_unlock(hdev);
return err;
}
static const struct mgmt_handler {
int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
u16 data_len);
......@@ -4846,9 +5688,16 @@ static const struct mgmt_handler {
{ 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 },
};
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
void *buf;
......@@ -4892,11 +5741,21 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
}
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);
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);
goto done;
}
}
if (opcode >= ARRAY_SIZE(mgmt_handlers) ||
......@@ -4907,8 +5766,15 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
goto done;
}
if ((hdev && opcode < MGMT_OP_READ_INFO) ||
(!hdev && opcode >= MGMT_OP_READ_INFO)) {
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;
}
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;
......@@ -4947,6 +5813,12 @@ void mgmt_index_added(struct hci_dev *hdev)
if (hdev->dev_type != HCI_BREDR)
return;
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return;
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
mgmt_event(MGMT_EV_UNCONF_INDEX_ADDED, hdev, NULL, 0, NULL);
else
mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
}
......@@ -4957,20 +5829,41 @@ void mgmt_index_removed(struct hci_dev *hdev)
if (hdev->dev_type != HCI_BREDR)
return;
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
return;
mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
mgmt_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, NULL);
else
mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
}
/* This function requires the caller holds hdev->lock */
static void restart_le_auto_conns(struct hci_dev *hdev)
static void restart_le_actions(struct hci_dev *hdev)
{
struct hci_conn_params *p;
list_for_each_entry(p, &hdev->le_conn_params, list) {
if (p->auto_connect == HCI_AUTO_CONN_ALWAYS)
hci_pend_le_conn_add(hdev, &p->addr, p->addr_type);
/* Needed for AUTO_OFF case where might not "really"
* have been powered off.
*/
list_del_init(&p->action);
switch (p->auto_connect) {
case HCI_AUTO_CONN_ALWAYS:
list_add(&p->action, &hdev->pend_le_conns);
break;
case HCI_AUTO_CONN_REPORT:
list_add(&p->action, &hdev->pend_le_reports);
break;
default:
break;
}
}
hci_update_background_scan(hdev);
}
static void powered_complete(struct hci_dev *hdev, u8 status)
......@@ -4981,7 +5874,7 @@ static void powered_complete(struct hci_dev *hdev, u8 status)
hci_dev_lock(hdev);
restart_le_auto_conns(hdev);
restart_le_actions(hdev);
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
......@@ -5190,6 +6083,14 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
if (!connectable && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
return;
/* If something else than mgmt changed the page scan state we
* can't differentiate this from a change triggered by adding
* the first element to the whitelist. Therefore, avoid
* incorrectly setting HCI_CONNECTABLE.
*/
if (connectable && !list_empty(&hdev->whitelist))
return;
if (connectable)
changed = !test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
else
......@@ -5199,18 +6100,6 @@ void mgmt_connectable(struct hci_dev *hdev, u8 connectable)
new_settings(hdev, NULL);
}
void mgmt_advertising(struct hci_dev *hdev, u8 advertising)
{
/* Powering off may stop advertising - don't let that interfere */
if (!advertising && mgmt_pending_find(MGMT_OP_SET_POWERED, hdev))
return;
if (advertising)
set_bit(HCI_ADVERTISING, &hdev->dev_flags);
else
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
}
void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
{
u8 mgmt_err = mgmt_status(status);
......@@ -5279,7 +6168,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
ev.key.ediv = key->ediv;
ev.key.rand = key->rand;
if (key->type == HCI_SMP_LTK)
if (key->type == SMP_LTK)
ev.key.master = 1;
memcpy(ev.key.val, key->val, sizeof(key->val));
......@@ -5347,6 +6236,27 @@ void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
}
void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 bdaddr_type, u8 store_hint, u16 min_interval,
u16 max_interval, u16 latency, u16 timeout)
{
struct mgmt_ev_new_conn_param ev;
if (!hci_is_identity_address(bdaddr, bdaddr_type))
return;
memset(&ev, 0, sizeof(ev));
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = link_to_bdaddr(LE_LINK, bdaddr_type);
ev.store_hint = store_hint;
ev.min_interval = cpu_to_le16(min_interval);
ev.max_interval = cpu_to_le16(max_interval);
ev.latency = cpu_to_le16(latency);
ev.timeout = cpu_to_le16(timeout);
mgmt_event(MGMT_EV_NEW_CONN_PARAM, hdev, &ev, sizeof(ev), NULL);
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len)
{
......@@ -5765,10 +6675,14 @@ 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_SSP_ENABLED, &hdev->dev_flags)) {
if (test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags))
hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
sizeof(enable), &enable);
update_eir(&req);
else
} else {
clear_eir(&req);
}
hci_req_run(&req, NULL);
}
......@@ -5912,17 +6826,23 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
}
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp,
u8 scan_rsp_len)
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 smp_irk *irk;
size_t ev_size;
if (!hci_discovery_active(hdev))
/* Don't send events for a non-kernel initiated discovery. With
* LE one exception is if we have pend_le_reports > 0 in which
* case we're doing passive scanning and want these events.
*/
if (!hci_discovery_active(hdev)) {
if (link_type == ACL_LINK)
return;
if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
return;
}
/* Make sure that the buffer is big enough. The 5 extra bytes
* are for the potential CoD field.
......@@ -5932,20 +6852,10 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
memset(buf, 0, sizeof(buf));
irk = hci_get_irk(hdev, bdaddr, addr_type);
if (irk) {
bacpy(&ev->addr.bdaddr, &irk->bdaddr);
ev->addr.type = link_to_bdaddr(link_type, irk->addr_type);
} else {
bacpy(&ev->addr.bdaddr, bdaddr);
ev->addr.type = link_to_bdaddr(link_type, addr_type);
}
ev->rssi = rssi;
if (cfm_name)
ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
if (!ssp)
ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
ev->flags = cpu_to_le32(flags);
if (eir_len > 0)
memcpy(ev->eir, eir, eir_len);
......@@ -6013,63 +6923,19 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering)
mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
}
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct pending_cmd *cmd;
struct mgmt_ev_device_blocked ev;
cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = type;
return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
cmd ? cmd->sk : NULL);
}
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct pending_cmd *cmd;
struct mgmt_ev_device_unblocked ev;
cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = type;
return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
cmd ? cmd->sk : NULL);
}
static void adv_enable_complete(struct hci_dev *hdev, u8 status)
{
BT_DBG("%s status %u", hdev->name, status);
/* Clear the advertising mgmt setting if we failed to re-enable it */
if (status) {
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
new_settings(hdev, NULL);
}
}
void mgmt_reenable_advertising(struct hci_dev *hdev)
{
struct hci_request req;
if (hci_conn_num(hdev, LE_LINK) > 0)
return;
if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
return;
hci_req_init(&req, hdev);
enable_advertising(&req);
/* If this fails we have no option but to let user space know
* that we've disabled advertising.
*/
if (hci_req_run(&req, adv_enable_complete) < 0) {
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
new_settings(hdev, NULL);
}
hci_req_run(&req, adv_enable_complete);
}
......@@ -35,11 +35,13 @@
#define AUTH_REQ_MASK 0x07
#define SMP_FLAG_TK_VALID 1
#define SMP_FLAG_CFM_PENDING 2
#define SMP_FLAG_MITM_AUTH 3
#define SMP_FLAG_COMPLETE 4
#define SMP_FLAG_INITIATOR 5
enum {
SMP_FLAG_TK_VALID,
SMP_FLAG_CFM_PENDING,
SMP_FLAG_MITM_AUTH,
SMP_FLAG_COMPLETE,
SMP_FLAG_INITIATOR,
};
struct smp_chan {
struct l2cap_conn *conn;
......@@ -60,20 +62,16 @@ struct smp_chan {
struct smp_ltk *slave_ltk;
struct smp_irk *remote_irk;
unsigned long flags;
struct crypto_blkcipher *tfm_aes;
};
static inline void swap128(const u8 src[16], u8 dst[16])
static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
{
int i;
for (i = 0; i < 16; i++)
dst[15 - i] = src[i];
}
size_t i;
static inline void swap56(const u8 src[7], u8 dst[7])
{
int i;
for (i = 0; i < 7; i++)
dst[6 - i] = src[i];
for (i = 0; i < len; i++)
dst[len - 1 - i] = src[i];
}
static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
......@@ -92,7 +90,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
desc.flags = 0;
/* The most significant octet of key corresponds to k[0] */
swap128(k, tmp);
swap_buf(k, tmp, 16);
err = crypto_blkcipher_setkey(tfm, tmp, 16);
if (err) {
......@@ -101,7 +99,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
}
/* Most significant octet of plaintextData corresponds to data[0] */
swap128(r, data);
swap_buf(r, data, 16);
sg_init_one(&sg, data, 16);
......@@ -110,7 +108,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
BT_ERR("Encrypt data error %d", err);
/* Most significant octet of encryptedData corresponds to data[0] */
swap128(data, r);
swap_buf(data, r, 16);
return err;
}
......@@ -174,13 +172,16 @@ int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa)
return 0;
}
static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
u8 _rat, bdaddr_t *ra, u8 res[16])
static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
u8 pres[7], u8 _iat, bdaddr_t *ia, u8 _rat, bdaddr_t *ra,
u8 res[16])
{
struct hci_dev *hdev = smp->conn->hcon->hdev;
u8 p1[16], p2[16];
int err;
BT_DBG("%s", hdev->name);
memset(p1, 0, 16);
/* p1 = pres || preq || _rat || _iat */
......@@ -198,7 +199,7 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
/* res = e(k, res) */
err = smp_e(tfm, k, res);
err = smp_e(smp->tfm_aes, k, res);
if (err) {
BT_ERR("Encrypt data error");
return err;
......@@ -208,23 +209,26 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
/* res = e(k, res) */
err = smp_e(tfm, k, res);
err = smp_e(smp->tfm_aes, k, res);
if (err)
BT_ERR("Encrypt data error");
return err;
}
static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
u8 r2[16], u8 _r[16])
static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
u8 _r[16])
{
struct hci_dev *hdev = smp->conn->hcon->hdev;
int err;
BT_DBG("%s", hdev->name);
/* Just least significant octets from r1 and r2 are considered */
memcpy(_r, r2, 8);
memcpy(_r + 8, r1, 8);
err = smp_e(tfm, k, _r);
err = smp_e(smp->tfm_aes, k, _r);
if (err)
BT_ERR("Encrypt data error");
......@@ -385,6 +389,16 @@ static const u8 gen_method[5][5] = {
{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP },
};
static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
{
/* If either side has unknown io_caps, use JUST WORKS */
if (local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY)
return JUST_WORKS;
return gen_method[remote_io][local_io];
}
static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
u8 local_io, u8 remote_io)
{
......@@ -401,14 +415,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
/* If neither side wants MITM, use JUST WORKS */
/* If either side has unknown io_caps, use JUST WORKS */
/* Otherwise, look up method from the table */
if (!(auth & SMP_AUTH_MITM) ||
local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY)
if (!(auth & SMP_AUTH_MITM))
method = JUST_WORKS;
else
method = gen_method[remote_io][local_io];
method = get_auth_method(smp, local_io, remote_io);
/* If not bonding, don't ask user to confirm a Zero TK */
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
......@@ -432,7 +443,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 (hcon->link_mode & HCI_LM_MASTER)
if (test_bit(HCI_CONN_MASTER, &hcon->flags))
method = CFM_PASSKEY;
else
method = REQ_PASSKEY;
......@@ -470,23 +481,15 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
static u8 smp_confirm(struct smp_chan *smp)
{
struct l2cap_conn *conn = smp->conn;
struct hci_dev *hdev = conn->hcon->hdev;
struct crypto_blkcipher *tfm = hdev->tfm_aes;
struct smp_cmd_pairing_confirm cp;
int ret;
BT_DBG("conn %p", conn);
/* Prevent mutual access to hdev->tfm_aes */
hci_dev_lock(hdev);
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->init_addr_type, &conn->hcon->init_addr,
conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
cp.confirm_val);
hci_dev_unlock(hdev);
if (ret)
return SMP_UNSPECIFIED;
......@@ -501,25 +504,17 @@ static u8 smp_random(struct smp_chan *smp)
{
struct l2cap_conn *conn = smp->conn;
struct hci_conn *hcon = conn->hcon;
struct hci_dev *hdev = hcon->hdev;
struct crypto_blkcipher *tfm = hdev->tfm_aes;
u8 confirm[16];
int ret;
if (IS_ERR_OR_NULL(tfm))
if (IS_ERR_OR_NULL(smp->tfm_aes))
return SMP_UNSPECIFIED;
BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
/* Prevent mutual access to hdev->tfm_aes */
hci_dev_lock(hdev);
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->init_addr_type, &hcon->init_addr,
hcon->resp_addr_type, &hcon->resp_addr, confirm);
hci_dev_unlock(hdev);
if (ret)
return SMP_UNSPECIFIED;
......@@ -533,7 +528,7 @@ static u8 smp_random(struct smp_chan *smp)
__le64 rand = 0;
__le16 ediv = 0;
smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);
smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
......@@ -543,6 +538,7 @@ static u8 smp_random(struct smp_chan *smp)
hci_le_start_enc(hcon, ediv, rand, stk);
hcon->enc_key_size = smp->enc_key_size;
set_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
} else {
u8 stk[16], auth;
__le64 rand = 0;
......@@ -551,7 +547,7 @@ static u8 smp_random(struct smp_chan *smp)
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
smp->prnd);
smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);
smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
......@@ -561,9 +557,12 @@ static u8 smp_random(struct smp_chan *smp)
else
auth = 0;
/* Even though there's no _SLAVE suffix this is the
* slave STK we're adding for later lookup (the master
* STK never needs to be stored).
*/
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
ediv, rand);
SMP_STK, auth, stk, smp->enc_key_size, ediv, rand);
}
return 0;
......@@ -577,9 +576,15 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
if (!smp)
return NULL;
smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(smp->tfm_aes)) {
BT_ERR("Unable to create ECB crypto context");
kfree(smp);
return NULL;
}
smp->conn = conn;
conn->smp_chan = smp;
conn->hcon->smp_conn = conn;
hci_conn_hold(conn->hcon);
......@@ -599,6 +604,8 @@ void smp_chan_destroy(struct l2cap_conn *conn)
kfree(smp->csrk);
kfree(smp->slave_csrk);
crypto_free_blkcipher(smp->tfm_aes);
/* If pairing failed clean up any keys we might have */
if (!complete) {
if (smp->ltk) {
......@@ -619,19 +626,18 @@ void smp_chan_destroy(struct l2cap_conn *conn)
kfree(smp);
conn->smp_chan = NULL;
conn->hcon->smp_conn = NULL;
hci_conn_drop(conn->hcon);
}
int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
{
struct l2cap_conn *conn = hcon->smp_conn;
struct l2cap_conn *conn = hcon->l2cap_data;
struct smp_chan *smp;
u32 value;
BT_DBG("");
if (!conn)
if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return -ENOTCONN;
smp = conn->smp_chan;
......@@ -669,7 +675,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_pairing rsp, *req = (void *) skb->data;
struct smp_chan *smp;
u8 key_size, auth;
u8 key_size, auth, sec_level;
int ret;
BT_DBG("conn %p", conn);
......@@ -677,7 +683,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 (conn->hcon->link_mode & HCI_LM_MASTER)
if (test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
......@@ -695,7 +701,19 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
/* We didn't start the pairing, so match remote */
auth = req->auth_req;
conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
sec_level = authreq_to_seclevel(auth);
if (sec_level > conn->hcon->pending_sec_level)
conn->hcon->pending_sec_level = sec_level;
/* If we need MITM check that it can be acheived */
if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
u8 method;
method = get_auth_method(smp, conn->hcon->io_capability,
req->io_capability);
if (method == JUST_WORKS || method == JUST_CFM)
return SMP_AUTH_REQUIREMENTS;
}
build_pairing_cmd(conn, req, &rsp, auth);
......@@ -732,7 +750,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 (!(conn->hcon->link_mode & HCI_LM_MASTER))
if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
skb_pull(skb, sizeof(*rsp));
......@@ -743,6 +761,16 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
if (check_enc_key_size(conn, key_size))
return SMP_ENC_KEY_SIZE;
/* If we need MITM check that it can be acheived */
if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
u8 method;
method = get_auth_method(smp, req->io_capability,
rsp->io_capability);
if (method == JUST_WORKS || method == JUST_CFM)
return SMP_AUTH_REQUIREMENTS;
}
get_random_bytes(smp->prnd, sizeof(smp->prnd));
smp->prsp[0] = SMP_CMD_PAIRING_RSP;
......@@ -810,7 +838,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
return smp_random(smp);
}
static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
{
struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
......@@ -818,18 +846,40 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type,
hcon->out);
if (!key)
return 0;
return false;
if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
return 0;
return false;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1;
return true;
hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
hcon->enc_key_size = key->enc_size;
return 1;
/* We never store STKs for master role, so clear this flag */
clear_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags);
return true;
}
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
{
if (sec_level == BT_SECURITY_LOW)
return true;
/* If we're encrypted with an STK always claim insufficient
* security. This way we allow the connection to be re-encrypted
* with an LTK, even if the LTK provides the same level of
* security.
*/
if (test_bit(HCI_CONN_STK_ENCRYPT, &hcon->flags))
return false;
if (hcon->sec_level >= sec_level)
return true;
return false;
}
static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
......@@ -838,16 +888,22 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
struct smp_cmd_pairing cp;
struct hci_conn *hcon = conn->hcon;
struct smp_chan *smp;
u8 sec_level;
BT_DBG("conn %p", conn);
if (skb->len < sizeof(*rp))
return SMP_INVALID_PARAMS;
if (!(conn->hcon->link_mode & HCI_LM_MASTER))
if (!test_bit(HCI_CONN_MASTER, &conn->hcon->flags))
return SMP_CMD_NOTSUPP;
hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
sec_level = authreq_to_seclevel(rp->auth_req);
if (smp_sufficient_security(hcon, sec_level))
return 0;
if (sec_level > hcon->pending_sec_level)
hcon->pending_sec_level = sec_level;
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
return 0;
......@@ -856,6 +912,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
return 0;
smp = smp_chan_create(conn);
if (!smp)
return SMP_UNSPECIFIED;
skb_pull(skb, sizeof(*rp));
......@@ -872,17 +930,6 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
return 0;
}
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level)
{
if (sec_level == BT_SECURITY_LOW)
return true;
if (hcon->sec_level >= sec_level)
return true;
return false;
}
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
{
struct l2cap_conn *conn = hcon->l2cap_data;
......@@ -901,9 +948,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
if (smp_sufficient_security(hcon, sec_level))
return 1;
if (hcon->link_mode & HCI_LM_MASTER)
if (smp_ltk_encrypt(conn, sec_level))
goto done;
if (sec_level > hcon->pending_sec_level)
hcon->pending_sec_level = sec_level;
if (test_bit(HCI_CONN_MASTER, &hcon->flags))
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
return 0;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
......@@ -918,10 +968,10 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
* requires it.
*/
if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
sec_level > BT_SECURITY_MEDIUM)
hcon->pending_sec_level > BT_SECURITY_MEDIUM)
authreq |= SMP_AUTH_MITM;
if (hcon->link_mode & HCI_LM_MASTER) {
if (test_bit(HCI_CONN_MASTER, &hcon->flags)) {
struct smp_cmd_pairing cp;
build_pairing_cmd(conn, &cp, NULL, authreq);
......@@ -937,9 +987,6 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
set_bit(SMP_FLAG_INITIATOR, &smp->flags);
done:
hcon->pending_sec_level = sec_level;
return 0;
}
......@@ -989,7 +1036,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
hci_dev_lock(hdev);
authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK,
ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
authenticated, smp->tk, smp->enc_key_size,
rp->ediv, rp->rand);
smp->ltk = ltk;
......@@ -1043,6 +1090,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
skb_pull(skb, sizeof(*info));
hci_dev_lock(hcon->hdev);
/* Strictly speaking the Core Specification (4.1) allows sending
* an empty address which would force us to rely on just the IRK
* as "identity information". However, since such
......@@ -1052,8 +1101,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
*/
if (!bacmp(&info->bdaddr, BDADDR_ANY)) {
BT_ERR("Ignoring IRK with no identity address");
smp_distribute_keys(conn);
return 0;
goto distribute;
}
bacpy(&smp->id_addr, &info->bdaddr);
......@@ -1067,8 +1115,11 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr,
smp->id_addr_type, smp->irk, &rpa);
distribute:
smp_distribute_keys(conn);
hci_dev_unlock(hcon->hdev);
return 0;
}
......@@ -1305,7 +1356,7 @@ int smp_distribute_keys(struct l2cap_conn *conn)
authenticated = hcon->sec_level == BT_SECURITY_HIGH;
ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_LTK_SLAVE, authenticated, enc.ltk,
SMP_LTK_SLAVE, authenticated, enc.ltk,
smp->enc_key_size, ediv, rand);
smp->slave_ltk = ltk;
......
......@@ -116,6 +116,13 @@ struct smp_cmd_security_req {
#define SMP_MIN_ENC_KEY_SIZE 7
#define SMP_MAX_ENC_KEY_SIZE 16
/* LTK types used in internal storage (struct smp_ltk) */
enum {
SMP_STK,
SMP_LTK,
SMP_LTK_SLAVE,
};
/* SMP Commands */
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
......
......@@ -1150,11 +1150,12 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
int err;
/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 6 + extra_len);
skb = dev_alloc_skb(local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN +
24 + 6 + extra_len + IEEE80211_WEP_ICV_LEN);
if (!skb)
return;
skb_reserve(skb, local->hw.extra_tx_headroom);
skb_reserve(skb, local->hw.extra_tx_headroom + IEEE80211_WEP_IV_LEN);
mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
memset(mgmt, 0, 24 + 6);
......
......@@ -424,7 +424,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
if (end >= start)
return jiffies_to_msecs(end - start);
return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
return jiffies_to_msecs(end + (ULONG_MAX - start) + 1);
}
void
......
......@@ -1498,18 +1498,17 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
}
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
#ifdef CONFIG_NL80211_TESTMODE
CMD(testmode_cmd, TESTMODE);
#endif
if (state->split) {
CMD(crit_proto_start, CRIT_PROTOCOL_START);
CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
CMD(channel_switch, CHANNEL_SWITCH);
}
CMD(set_qos_map, SET_QOS_MAP);
#ifdef CONFIG_NL80211_TESTMODE
CMD(testmode_cmd, TESTMODE);
#endif
}
/* add into the if now */
#undef CMD
if (rdev->ops->connect || rdev->ops->auth) {
......
......@@ -935,7 +935,7 @@ freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq,
if (!band_rule_found)
band_rule_found = freq_in_rule_band(fr, center_freq);
bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(5));
bw_fits = reg_does_bw_fit(fr, center_freq, MHZ_TO_KHZ(20));
if (band_rule_found && bw_fits)
return rr;
......@@ -1019,10 +1019,10 @@ static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
}
#endif
/* Find an ieee80211_reg_rule such that a 5MHz channel with frequency
* chan->center_freq fits there.
* If there is no such reg_rule, disable the channel, otherwise set the
* flags corresponding to the bandwidths allowed in the particular reg_rule
/*
* Note that right now we assume the desired channel bandwidth
* is always 20 MHz for each individual channel (HT40 uses 20 MHz
* per channel, the primary and the extension channel).
*/
static void handle_channel(struct wiphy *wiphy,
enum nl80211_reg_initiator initiator,
......@@ -1083,12 +1083,8 @@ static void handle_channel(struct wiphy *wiphy,
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
if (max_bandwidth_khz < MHZ_TO_KHZ(10))
bw_flags = IEEE80211_CHAN_NO_10MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(20))
bw_flags |= IEEE80211_CHAN_NO_20MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
bw_flags |= IEEE80211_CHAN_NO_HT40;
bw_flags = IEEE80211_CHAN_NO_HT40;
if (max_bandwidth_khz < MHZ_TO_KHZ(80))
bw_flags |= IEEE80211_CHAN_NO_80MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(160))
......@@ -1522,12 +1518,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
if (max_bandwidth_khz < MHZ_TO_KHZ(10))
bw_flags = IEEE80211_CHAN_NO_10MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(20))
bw_flags |= IEEE80211_CHAN_NO_20MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(40))
bw_flags |= IEEE80211_CHAN_NO_HT40;
bw_flags = IEEE80211_CHAN_NO_HT40;
if (max_bandwidth_khz < MHZ_TO_KHZ(80))
bw_flags |= IEEE80211_CHAN_NO_80MHZ;
if (max_bandwidth_khz < MHZ_TO_KHZ(160))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册