Commit 0111ad82 authored by David S. Miller's avatar David S. Miller
parents e427babe fdde0a26
......@@ -65,12 +65,14 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) },
{ USB_DEVICE(0x0930, 0x0215) },
{ USB_DEVICE(0x0489, 0xE03D) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x13d3, 0x3375) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
......@@ -87,6 +89,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */
};
......
......@@ -411,7 +411,7 @@ static void bfusb_rx_complete(struct urb *urb)
static int bfusb_open(struct hci_dev *hdev)
{
struct bfusb_data *data = hdev->driver_data;
struct bfusb_data *data = hci_get_drvdata(hdev);
unsigned long flags;
int i, err;
......@@ -437,7 +437,7 @@ static int bfusb_open(struct hci_dev *hdev)
static int bfusb_flush(struct hci_dev *hdev)
{
struct bfusb_data *data = hdev->driver_data;
struct bfusb_data *data = hci_get_drvdata(hdev);
BT_DBG("hdev %p bfusb %p", hdev, data);
......@@ -448,7 +448,7 @@ static int bfusb_flush(struct hci_dev *hdev)
static int bfusb_close(struct hci_dev *hdev)
{
struct bfusb_data *data = hdev->driver_data;
struct bfusb_data *data = hci_get_drvdata(hdev);
unsigned long flags;
BT_DBG("hdev %p bfusb %p", hdev, data);
......@@ -483,7 +483,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hdev->driver_data;
data = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
......@@ -544,15 +544,6 @@ static int bfusb_send_frame(struct sk_buff *skb)
return 0;
}
static void bfusb_destruct(struct hci_dev *hdev)
{
struct bfusb_data *data = hdev->driver_data;
BT_DBG("hdev %p bfusb %p", hdev, data);
kfree(data);
}
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
......@@ -705,18 +696,15 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
data->hdev = hdev;
hdev->bus = HCI_USB;
hdev->driver_data = data;
hci_set_drvdata(hdev, data);
SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = bfusb_open;
hdev->close = bfusb_close;
hdev->flush = bfusb_flush;
hdev->send = bfusb_send_frame;
hdev->destruct = bfusb_destruct;
hdev->ioctl = bfusb_ioctl;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
......@@ -753,6 +741,7 @@ static void bfusb_disconnect(struct usb_interface *intf)
hci_unregister_dev(hdev);
hci_free_dev(hdev);
kfree(data);
}
static struct usb_driver bfusb_driver = {
......
......@@ -561,7 +561,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
{
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
bluecard_info_t *info = hci_get_drvdata(hdev);
struct sk_buff *skb;
/* Ericsson baud rate command */
......@@ -609,7 +609,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
static int bluecard_hci_flush(struct hci_dev *hdev)
{
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
bluecard_info_t *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
......@@ -620,7 +620,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
bluecard_info_t *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
......@@ -640,7 +640,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
bluecard_info_t *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
......@@ -667,7 +667,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = (bluecard_info_t *)(hdev->driver_data);
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
......@@ -691,11 +691,6 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
}
static void bluecard_hci_destruct(struct hci_dev *hdev)
{
}
static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
......@@ -734,18 +729,15 @@ static int bluecard_open(bluecard_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hdev->driver_data = info;
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bluecard_hci_open;
hdev->close = bluecard_hci_close;
hdev->flush = bluecard_hci_flush;
hdev->send = bluecard_hci_send_frame;
hdev->destruct = bluecard_hci_destruct;
hdev->ioctl = bluecard_hci_ioctl;
hdev->owner = THIS_MODULE;
id = inb(iobase + 0x30);
if ((id & 0x0f) == 0x02)
......
......@@ -66,7 +66,7 @@ struct hci_vendor_hdr {
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
BT_DBG("%s queue %d buffer %p count %d", hdev->name,
queue, buf, count);
......@@ -189,7 +189,7 @@ static void bpa10x_tx_complete(struct urb *urb)
static void bpa10x_rx_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
......@@ -219,7 +219,7 @@ static void bpa10x_rx_complete(struct urb *urb)
static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
......@@ -260,7 +260,7 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
......@@ -301,7 +301,7 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
static int bpa10x_open(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s", hdev->name);
......@@ -329,7 +329,7 @@ static int bpa10x_open(struct hci_dev *hdev)
static int bpa10x_close(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -343,7 +343,7 @@ static int bpa10x_close(struct hci_dev *hdev)
static int bpa10x_flush(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -355,7 +355,7 @@ static int bpa10x_flush(struct hci_dev *hdev)
static int bpa10x_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct bpa10x_data *data = hdev->driver_data;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
unsigned int pipe;
......@@ -432,17 +432,6 @@ static int bpa10x_send_frame(struct sk_buff *skb)
return 0;
}
static void bpa10x_destruct(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree_skb(data->rx_skb[0]);
kfree_skb(data->rx_skb[1]);
kfree(data);
}
static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct bpa10x_data *data;
......@@ -470,7 +459,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
}
hdev->bus = HCI_USB;
hdev->driver_data = data;
hci_set_drvdata(hdev, data);
data->hdev = hdev;
......@@ -480,9 +469,6 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
hdev->close = bpa10x_close;
hdev->flush = bpa10x_flush;
hdev->send = bpa10x_send_frame;
hdev->destruct = bpa10x_destruct;
hdev->owner = THIS_MODULE;
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
......@@ -512,6 +498,9 @@ static void bpa10x_disconnect(struct usb_interface *intf)
hci_unregister_dev(data->hdev);
hci_free_dev(data->hdev);
kfree_skb(data->rx_skb[0]);
kfree_skb(data->rx_skb[1]);
kfree(data);
}
static struct usb_driver bpa10x_driver = {
......
......@@ -389,7 +389,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
static int bt3c_hci_flush(struct hci_dev *hdev)
{
bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
bt3c_info_t *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
......@@ -428,7 +428,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = (bt3c_info_t *) (hdev->driver_data);
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
......@@ -456,11 +456,6 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
}
static void bt3c_hci_destruct(struct hci_dev *hdev)
{
}
static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
......@@ -580,18 +575,15 @@ static int bt3c_open(bt3c_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hdev->driver_data = info;
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bt3c_hci_open;
hdev->close = bt3c_hci_close;
hdev->flush = bt3c_hci_flush;
hdev->send = bt3c_hci_send_frame;
hdev->destruct = bt3c_hci_destruct;
hdev->ioctl = bt3c_hci_ioctl;
hdev->owner = THIS_MODULE;
/* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
if (err < 0) {
......
......@@ -384,7 +384,7 @@ static const struct file_operations btmrvl_txdnldready_fops = {
void btmrvl_debugfs_init(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_debugfs_data *dbg;
if (!hdev->debugfs)
......@@ -401,36 +401,34 @@ void btmrvl_debugfs_init(struct hci_dev *hdev)
dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_psmode_fops);
priv, &btmrvl_psmode_fops);
dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_pscmd_fops);
priv, &btmrvl_pscmd_fops);
dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_gpiogap_fops);
priv, &btmrvl_gpiogap_fops);
dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_hsmode_fops);
priv, &btmrvl_hsmode_fops);
dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_hscmd_fops);
priv, &btmrvl_hscmd_fops);
dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
hdev->driver_data, &btmrvl_hscfgcmd_fops);
priv, &btmrvl_hscfgcmd_fops);
dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
dbg->status_dir,
hdev->driver_data,
&btmrvl_curpsmode_fops);
dbg->status_dir, priv,
&btmrvl_curpsmode_fops);
dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir,
hdev->driver_data, &btmrvl_psstate_fops);
priv, &btmrvl_psstate_fops);
dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir,
hdev->driver_data, &btmrvl_hsstate_fops);
priv, &btmrvl_hsstate_fops);
dbg->txdnldready = debugfs_create_file("txdnldready", 0444,
dbg->status_dir,
hdev->driver_data,
&btmrvl_txdnldready_fops);
dbg->status_dir, priv,
&btmrvl_txdnldready_fops);
}
void btmrvl_debugfs_remove(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
if (!dbg)
......
......@@ -387,10 +387,6 @@ static int btmrvl_ioctl(struct hci_dev *hdev,
return -ENOIOCTLCMD;
}
static void btmrvl_destruct(struct hci_dev *hdev)
{
}
static int btmrvl_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
......@@ -398,12 +394,13 @@ static int btmrvl_send_frame(struct sk_buff *skb)
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
if (!hdev || !hdev->driver_data) {
if (!hdev) {
BT_ERR("Frame for unknown HCI device");
return -ENODEV;
}
priv = (struct btmrvl_private *) hdev->driver_data;
priv = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags)) {
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
......@@ -434,7 +431,7 @@ static int btmrvl_send_frame(struct sk_buff *skb)
static int btmrvl_flush(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_private *priv = hci_get_drvdata(hdev);
skb_queue_purge(&priv->adapter->tx_queue);
......@@ -443,7 +440,7 @@ static int btmrvl_flush(struct hci_dev *hdev)
static int btmrvl_close(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_private *priv = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
......@@ -546,16 +543,14 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
}
priv->btmrvl_dev.hcidev = hdev;
hdev->driver_data = priv;
hci_set_drvdata(hdev, priv);
hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open;
hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame;
hdev->destruct = btmrvl_destruct;
hdev->ioctl = btmrvl_ioctl;
hdev->owner = THIS_MODULE;
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
......
......@@ -189,7 +189,7 @@ static void btsdio_interrupt(struct sdio_func *func)
static int btsdio_open(struct hci_dev *hdev)
{
struct btsdio_data *data = hdev->driver_data;
struct btsdio_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s", hdev->name);
......@@ -225,7 +225,7 @@ static int btsdio_open(struct hci_dev *hdev)
static int btsdio_close(struct hci_dev *hdev)
{
struct btsdio_data *data = hdev->driver_data;
struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -246,7 +246,7 @@ static int btsdio_close(struct hci_dev *hdev)
static int btsdio_flush(struct hci_dev *hdev)
{
struct btsdio_data *data = hdev->driver_data;
struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -258,7 +258,7 @@ static int btsdio_flush(struct hci_dev *hdev)
static int btsdio_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btsdio_data *data = hdev->driver_data;
struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -289,15 +289,6 @@ static int btsdio_send_frame(struct sk_buff *skb)
return 0;
}
static void btsdio_destruct(struct hci_dev *hdev)
{
struct btsdio_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree(data);
}
static int btsdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
......@@ -330,7 +321,7 @@ static int btsdio_probe(struct sdio_func *func,
}
hdev->bus = HCI_SDIO;
hdev->driver_data = data;
hci_set_drvdata(hdev, data);
if (id->class == SDIO_CLASS_BT_AMP)
hdev->dev_type = HCI_AMP;
......@@ -345,9 +336,6 @@ static int btsdio_probe(struct sdio_func *func,
hdev->close = btsdio_close;
hdev->flush = btsdio_flush;
hdev->send = btsdio_send_frame;
hdev->destruct = btsdio_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev);
if (err < 0) {
......@@ -378,6 +366,7 @@ static void btsdio_remove(struct sdio_func *func)
hci_unregister_dev(hdev);
hci_free_dev(hdev);
kfree(data);
}
static struct sdio_driver btsdio_driver = {
......
......@@ -397,7 +397,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
static int btuart_hci_flush(struct hci_dev *hdev)
{
btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
btuart_info_t *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
......@@ -435,7 +435,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = (btuart_info_t *)(hdev->driver_data);
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
......@@ -459,11 +459,6 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
}
static void btuart_hci_destruct(struct hci_dev *hdev)
{
}
static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
......@@ -498,18 +493,15 @@ static int btuart_open(btuart_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hdev->driver_data = info;
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = btuart_hci_open;
hdev->close = btuart_hci_close;
hdev->flush = btuart_hci_flush;
hdev->send = btuart_hci_send_frame;
hdev->destruct = btuart_hci_destruct;
hdev->ioctl = btuart_hci_ioctl;
hdev->owner = THIS_MODULE;
spin_lock_irqsave(&(info->lock), flags);
/* Reset UART */
......
......@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
......@@ -121,12 +122,14 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
......@@ -243,7 +246,7 @@ static int inc_tx(struct btusb_data *data)
static void btusb_intr_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
......@@ -282,7 +285,7 @@ static void btusb_intr_complete(struct urb *urb)
static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
......@@ -331,7 +334,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
static void btusb_bulk_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
......@@ -370,7 +373,7 @@ static void btusb_bulk_complete(struct urb *urb)
static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
......@@ -417,7 +420,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
static void btusb_isoc_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
int i, err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
......@@ -484,7 +487,7 @@ static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
......@@ -537,7 +540,7 @@ static void btusb_tx_complete(struct urb *urb)
{
struct sk_buff *skb = urb->context;
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
BT_DBG("%s urb %p status %d count %d", hdev->name,
urb, urb->status, urb->actual_length);
......@@ -584,7 +587,7 @@ static void btusb_isoc_tx_complete(struct urb *urb)
static int btusb_open(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s", hdev->name);
......@@ -634,7 +637,7 @@ static void btusb_stop_traffic(struct btusb_data *data)
static int btusb_close(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
int err;
BT_DBG("%s", hdev->name);
......@@ -664,7 +667,7 @@ static int btusb_close(struct hci_dev *hdev)
static int btusb_flush(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
......@@ -676,7 +679,7 @@ static int btusb_flush(struct hci_dev *hdev)
static int btusb_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
unsigned int pipe;
......@@ -784,18 +787,9 @@ static int btusb_send_frame(struct sk_buff *skb)
return err;
}
static void btusb_destruct(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree(data);
}
static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
BT_DBG("%s evt %d", hdev->name, evt);
......@@ -807,7 +801,7 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
{
struct btusb_data *data = hdev->driver_data;
struct btusb_data *data = hci_get_drvdata(hdev);
struct usb_interface *intf = data->isoc;
struct usb_endpoint_descriptor *ep_desc;
int i, err;
......@@ -995,7 +989,7 @@ static int btusb_probe(struct usb_interface *intf,
}
hdev->bus = HCI_USB;
hdev->driver_data = data;
hci_set_drvdata(hdev, data);
data->hdev = hdev;
......@@ -1005,11 +999,8 @@ static int btusb_probe(struct usb_interface *intf,
hdev->close = btusb_close;
hdev->flush = btusb_flush;
hdev->send = btusb_send_frame;
hdev->destruct = btusb_destruct;
hdev->notify = btusb_notify;
hdev->owner = THIS_MODULE;
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
......@@ -1091,9 +1082,6 @@ static void btusb_disconnect(struct usb_interface *intf)
return;
hdev = data->hdev;
__hci_dev_hold(hdev);
usb_set_intfdata(data->intf, NULL);
if (data->isoc)
......@@ -1106,9 +1094,8 @@ static void btusb_disconnect(struct usb_interface *intf)
else if (data->isoc)
usb_driver_release_interface(&btusb_driver, data->isoc);
__hci_dev_put(hdev);
hci_free_dev(hdev);
kfree(data);
}
#ifdef CONFIG_PM
......
......@@ -161,7 +161,7 @@ static int ti_st_open(struct hci_dev *hdev)
return -EBUSY;
/* provide contexts for callbacks from ST */
hst = hdev->driver_data;
hst = hci_get_drvdata(hdev);
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
ti_st_proto[i].priv_data = hst;
......@@ -236,7 +236,7 @@ static int ti_st_open(struct hci_dev *hdev)
static int ti_st_close(struct hci_dev *hdev)
{
int err, i;
struct ti_st *hst = hdev->driver_data;
struct ti_st *hst = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
......@@ -264,7 +264,7 @@ static int ti_st_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hst = hdev->driver_data;
hst = hci_get_drvdata(hdev);
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
......@@ -291,14 +291,6 @@ static int ti_st_send_frame(struct sk_buff *skb)
return 0;
}
static void ti_st_destruct(struct hci_dev *hdev)
{
BT_DBG("%s", hdev->name);
/* do nothing here, since platform remove
* would free the hdev->driver_data
*/
}
static int bt_ti_probe(struct platform_device *pdev)
{
static struct ti_st *hst;
......@@ -320,13 +312,11 @@ static int bt_ti_probe(struct platform_device *pdev)
hst->hdev = hdev;
hdev->bus = HCI_UART;
hdev->driver_data = hst;
hci_set_drvdata(hdev, hst);
hdev->open = ti_st_open;
hdev->close = ti_st_close;
hdev->flush = NULL;
hdev->send = ti_st_send_frame;
hdev->destruct = ti_st_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev);
if (err < 0) {
......
......@@ -83,9 +83,6 @@ typedef struct dtl1_info_t {
static int dtl1_config(struct pcmcia_device *link);
static void dtl1_release(struct pcmcia_device *link);
static void dtl1_detach(struct pcmcia_device *p_dev);
/* Transmit states */
......@@ -367,7 +364,7 @@ static int dtl1_hci_open(struct hci_dev *hdev)
static int dtl1_hci_flush(struct hci_dev *hdev)
{
dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
dtl1_info_t *info = hci_get_drvdata(hdev);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
......@@ -399,7 +396,7 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = (dtl1_info_t *)(hdev->driver_data);
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
......@@ -442,11 +439,6 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
}
static void dtl1_hci_destruct(struct hci_dev *hdev)
{
}
static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
......@@ -483,18 +475,15 @@ static int dtl1_open(dtl1_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hdev->driver_data = info;
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = dtl1_hci_open;
hdev->close = dtl1_hci_close;
hdev->flush = dtl1_hci_flush;
hdev->send = dtl1_hci_send_frame;
hdev->destruct = dtl1_hci_destruct;
hdev->ioctl = dtl1_hci_ioctl;
hdev->owner = THIS_MODULE;
spin_lock_irqsave(&(info->lock), flags);
/* Reset UART */
......@@ -579,8 +568,8 @@ static void dtl1_detach(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
dtl1_release(link);
dtl1_close(info);
pcmcia_disable_device(link);
kfree(info);
}
......@@ -619,21 +608,10 @@ static int dtl1_config(struct pcmcia_device *link)
return 0;
failed:
dtl1_release(link);
dtl1_detach(link);
return -ENODEV;
}
static void dtl1_release(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
dtl1_close(info);
pcmcia_disable_device(link);
}
static const struct pcmcia_device_id dtl1_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
......
......@@ -112,7 +112,7 @@ static int ath_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
ath = kzalloc(sizeof(*ath), GFP_KERNEL);
if (!ath)
return -ENOMEM;
......
......@@ -692,7 +692,7 @@ static int bcsp_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
bcsp = kzalloc(sizeof(*bcsp), GFP_KERNEL);
if (!bcsp)
return -ENOMEM;
......
......@@ -69,7 +69,7 @@ static int h4_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
h4 = kzalloc(sizeof(*h4), GFP_KERNEL);
if (!h4)
return -ENOMEM;
......
......@@ -48,8 +48,6 @@
#define VERSION "2.2"
static bool reset = 0;
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
int hci_uart_register_proto(struct hci_uart_proto *p)
......@@ -174,7 +172,7 @@ static int hci_uart_open(struct hci_dev *hdev)
/* Reset device */
static int hci_uart_flush(struct hci_dev *hdev)
{
struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
struct hci_uart *hu = hci_get_drvdata(hdev);
struct tty_struct *tty = hu->tty;
BT_DBG("hdev %p tty %p", hdev, tty);
......@@ -220,7 +218,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hu = (struct hci_uart *) hdev->driver_data;
hu = hci_get_drvdata(hdev);
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
......@@ -231,15 +229,6 @@ static int hci_uart_send_frame(struct sk_buff *skb)
return 0;
}
static void hci_uart_destruct(struct hci_dev *hdev)
{
if (!hdev)
return;
BT_DBG("%s", hdev->name);
kfree(hdev->driver_data);
}
/* ------ LDISC part ------ */
/* hci_uart_tty_open
*
......@@ -316,6 +305,8 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hci_free_dev(hdev);
}
}
kfree(hu);
}
}
......@@ -391,22 +382,24 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hu->hdev = hdev;
hdev->bus = HCI_UART;
hdev->driver_data = hu;
hci_set_drvdata(hdev, hu);
hdev->open = hci_uart_open;
hdev->close = hci_uart_close;
hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame;
hdev->destruct = hci_uart_destruct;
hdev->parent = hu->tty->dev;
hdev->owner = THIS_MODULE;
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
if (!reset)
if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
hdev->dev_type = HCI_AMP;
else
hdev->dev_type = HCI_BREDR;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
......@@ -594,9 +587,6 @@ static void __exit hci_uart_exit(void)
module_init(hci_uart_init);
module_exit(hci_uart_exit);
module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
MODULE_VERSION(VERSION);
......
......@@ -125,7 +125,7 @@ static int ll_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
ll = kzalloc(sizeof(*ll), GFP_KERNEL);
if (!ll)
return -ENOMEM;
......
......@@ -45,6 +45,8 @@
#define HCI_UART_ATH3K 5
#define HCI_UART_RAW_DEVICE 0
#define HCI_UART_RESET_ON_INIT 1
#define HCI_UART_CREATE_AMP 2
struct hci_uart;
......
......@@ -61,7 +61,7 @@ static int vhci_open_dev(struct hci_dev *hdev)
static int vhci_close_dev(struct hci_dev *hdev)
{
struct vhci_data *data = hdev->driver_data;
struct vhci_data *data = hci_get_drvdata(hdev);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
......@@ -73,7 +73,7 @@ static int vhci_close_dev(struct hci_dev *hdev)
static int vhci_flush(struct hci_dev *hdev)
{
struct vhci_data *data = hdev->driver_data;
struct vhci_data *data = hci_get_drvdata(hdev);
skb_queue_purge(&data->readq);
......@@ -93,7 +93,7 @@ static int vhci_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hdev->driver_data;
data = hci_get_drvdata(hdev);
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb);
......@@ -103,11 +103,6 @@ static int vhci_send_frame(struct sk_buff *skb)
return 0;
}
static void vhci_destruct(struct hci_dev *hdev)
{
kfree(hdev->driver_data);
}
static inline ssize_t vhci_get_user(struct vhci_data *data,
const char __user *buf, size_t count)
{
......@@ -239,7 +234,7 @@ static int vhci_open(struct inode *inode, struct file *file)
data->hdev = hdev;
hdev->bus = HCI_VIRTUAL;
hdev->driver_data = data;
hci_set_drvdata(hdev, data);
if (amp)
hdev->dev_type = HCI_AMP;
......@@ -248,9 +243,6 @@ static int vhci_open(struct inode *inode, struct file *file)
hdev->close = vhci_close_dev;
hdev->flush = vhci_flush;
hdev->send = vhci_send_frame;
hdev->destruct = vhci_destruct;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
......@@ -273,6 +265,7 @@ static int vhci_release(struct inode *inode, struct file *file)
hci_free_dev(hdev);
file->private_data = NULL;
kfree(data);
return 0;
}
......
......@@ -109,12 +109,14 @@ struct bt_power {
*/
#define BT_CHANNEL_POLICY_AMP_PREFERRED 2
__printf(2, 3)
int bt_printk(const char *level, const char *fmt, ...);
__printf(1, 2)
int bt_info(const char *fmt, ...);
__printf(1, 2)
int bt_err(const char *fmt, ...);
#define BT_INFO(fmt, arg...) bt_printk(KERN_INFO, pr_fmt(fmt), ##arg)
#define BT_ERR(fmt, arg...) bt_printk(KERN_ERR, pr_fmt(fmt), ##arg)
#define BT_DBG(fmt, arg...) pr_debug(fmt "\n", ##arg)
#define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__)
#define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__)
#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__)
/* Connection and socket states */
enum {
......@@ -129,6 +131,33 @@ enum {
BT_CLOSED
};
/* If unused will be removed by compiler */
static inline const char *state_to_string(int state)
{
switch (state) {
case BT_CONNECTED:
return "BT_CONNECTED";
case BT_OPEN:
return "BT_OPEN";
case BT_BOUND:
return "BT_BOUND";
case BT_LISTEN:
return "BT_LISTEN";
case BT_CONNECT:
return "BT_CONNECT";
case BT_CONNECT2:
return "BT_CONNECT2";
case BT_CONFIG:
return "BT_CONFIG";
case BT_DISCONN:
return "BT_DISCONN";
case BT_CLOSED:
return "BT_CLOSED";
}
return "invalid state";
}
/* BD Address */
typedef struct {
__u8 b[6];
......@@ -193,7 +222,6 @@ struct bt_skb_cb {
__u16 tx_seq;
__u8 retries;
__u8 sar;
unsigned short channel;
__u8 force_active;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
......
......@@ -77,14 +77,6 @@ enum {
HCI_RAW,
HCI_SETUP,
HCI_AUTO_OFF,
HCI_MGMT,
HCI_PAIRABLE,
HCI_SERVICE_CACHE,
HCI_LINK_KEYS,
HCI_DEBUG_KEYS,
HCI_RESET,
};
......@@ -93,7 +85,22 @@ enum {
* states from the controller.
*/
enum {
HCI_SETUP,
HCI_AUTO_OFF,
HCI_MGMT,
HCI_PAIRABLE,
HCI_SERVICE_CACHE,
HCI_LINK_KEYS,
HCI_DEBUG_KEYS,
HCI_LE_SCAN,
HCI_SSP_ENABLED,
HCI_HS_ENABLED,
HCI_LE_ENABLED,
HCI_CONNECTABLE,
HCI_DISCOVERABLE,
HCI_LINK_SECURITY,
HCI_PENDING_CLASS,
};
/* HCI ioctl defines */
......@@ -130,6 +137,7 @@ enum {
#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */
#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */
#define HCI_CMD_TIMEOUT (1000) /* 1 seconds */
#define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
......@@ -229,7 +237,9 @@ enum {
#define LMP_EXTFEATURES 0x80
/* Extended LMP features */
#define LMP_HOST_LE 0x02
#define LMP_HOST_SSP 0x01
#define LMP_HOST_LE 0x02
#define LMP_HOST_LE_BREDR 0x04
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
......@@ -268,10 +278,11 @@ enum {
#define HCI_LK_UNAUTH_COMBINATION 0x04
#define HCI_LK_AUTH_COMBINATION 0x05
#define HCI_LK_CHANGED_COMBINATION 0x06
/* The spec doesn't define types for SMP keys */
#define HCI_LK_SMP_LTK 0x81
#define HCI_LK_SMP_IRK 0x82
#define HCI_LK_SMP_CSRK 0x83
/* 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
/* ---- HCI Error Codes ---- */
#define HCI_ERROR_AUTH_FAILURE 0x05
......@@ -284,6 +295,22 @@ enum {
#define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00
#define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01
/* Extended Inquiry Response field types */
#define EIR_FLAGS 0x01 /* flags */
#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
#define EIR_NAME_SHORT 0x08 /* shortened local name */
#define EIR_NAME_COMPLETE 0x09 /* complete local name */
#define EIR_TX_POWER 0x0A /* transmit power level */
#define EIR_CLASS_OF_DEV 0x0D /* Class of Device */
#define EIR_SSP_HASH_C 0x0E /* Simple Pairing Hash C */
#define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */
#define EIR_DEVICE_ID 0x10 /* device ID */
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
......@@ -666,8 +693,8 @@ struct hci_cp_host_buffer_size {
#define HCI_OP_WRITE_EIR 0x0c52
struct hci_cp_write_eir {
uint8_t fec;
uint8_t data[HCI_MAX_EIR_LENGTH];
__u8 fec;
__u8 data[HCI_MAX_EIR_LENGTH];
} __packed;
#define HCI_OP_READ_SSP_MODE 0x0c55
......@@ -698,8 +725,8 @@ struct hci_rp_read_flow_control_mode {
#define HCI_OP_WRITE_LE_HOST_SUPPORTED 0x0c6d
struct hci_cp_write_le_host_supported {
__u8 le;
__u8 simul;
__u8 le;
__u8 simul;
} __packed;
#define HCI_OP_READ_LOCAL_VERSION 0x1001
......@@ -1155,6 +1182,19 @@ struct hci_ev_le_meta {
__u8 subevent;
} __packed;
#define HCI_EV_NUM_COMP_BLOCKS 0x48
struct hci_comp_blocks_info {
__le16 handle;
__le16 pkts;
__le16 blocks;
} __packed;
struct hci_ev_num_comp_blocks {
__le16 num_blocks;
__u8 num_hndl;
struct hci_comp_blocks_info handles[0];
} __packed;
/* Low energy meta events */
#define HCI_EV_LE_CONN_COMPLETE 0x01
struct hci_ev_le_conn_complete {
......@@ -1288,6 +1328,7 @@ struct sockaddr_hci {
#define HCI_CHANNEL_RAW 0
#define HCI_CHANNEL_CONTROL 1
#define HCI_CHANNEL_MONITOR 2
struct hci_filter {
unsigned long type_mask;
......@@ -1389,5 +1430,6 @@ struct hci_inquiry_req {
#define IREQ_CACHE_FLUSH 0x0001
extern bool enable_hs;
extern bool enable_le;
#endif /* __HCI_H */
......@@ -44,14 +44,31 @@ struct inquiry_data {
};
struct inquiry_entry {
struct inquiry_entry *next;
struct list_head all; /* inq_cache.all */
struct list_head list; /* unknown or resolve */
enum {
NAME_NOT_KNOWN,
NAME_NEEDED,
NAME_PENDING,
NAME_KNOWN,
} name_state;
__u32 timestamp;
struct inquiry_data data;
};
struct inquiry_cache {
struct discovery_state {
int type;
enum {
DISCOVERY_STOPPED,
DISCOVERY_STARTING,
DISCOVERY_FINDING,
DISCOVERY_RESOLVING,
DISCOVERY_STOPPING,
} state;
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
__u32 timestamp;
struct inquiry_entry *list;
};
struct hci_conn_hash {
......@@ -72,18 +89,16 @@ struct bt_uuid {
u8 svc_hint;
};
struct key_master_id {
__le16 ediv;
u8 rand[8];
} __packed;
struct link_key_data {
struct smp_ltk {
struct list_head list;
bdaddr_t bdaddr;
u8 bdaddr_type;
u8 authenticated;
u8 type;
u8 enc_size;
__le16 ediv;
u8 rand[8];
u8 val[16];
u8 pin_len;
u8 dlen;
u8 data[0];
} __packed;
struct link_key {
......@@ -92,8 +107,6 @@ struct link_key {
u8 type;
u8 val[16];
u8 pin_len;
u8 dlen;
u8 data[0];
};
struct oob_data {
......@@ -109,11 +122,19 @@ struct adv_entry {
u8 bdaddr_type;
};
struct le_scan_params {
u8 type;
u16 interval;
u16 window;
int timeout;
};
#define HCI_MAX_SHORT_NAME_LENGTH 10
#define NUM_REASSEMBLY 4
struct hci_dev {
struct list_head list;
struct mutex lock;
atomic_t refcnt;
char name[8];
unsigned long flags;
......@@ -122,6 +143,7 @@ struct hci_dev {
__u8 dev_type;
bdaddr_t bdaddr;
__u8 dev_name[HCI_MAX_NAME_LENGTH];
__u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
__u8 eir[HCI_MAX_EIR_LENGTH];
__u8 dev_class[3];
__u8 major_class;
......@@ -129,7 +151,6 @@ struct hci_dev {
__u8 features[8];
__u8 host_features[8];
__u8 commands[64];
__u8 ssp_mode;
__u8 hci_ver;
__u16 hci_rev;
__u8 lmp_ver;
......@@ -217,7 +238,7 @@ struct hci_dev {
struct list_head mgmt_pending;
struct inquiry_cache inq_cache;
struct discovery_state discovery;
struct hci_conn_hash conn_hash;
struct list_head blacklist;
......@@ -225,6 +246,8 @@ struct hci_dev {
struct list_head link_keys;
struct list_head long_term_keys;
struct list_head remote_oob_data;
struct list_head adv_entries;
......@@ -234,7 +257,6 @@ struct hci_dev {
struct sk_buff_head driver_init;
void *driver_data;
void *core_data;
atomic_t promisc;
......@@ -246,15 +268,17 @@ struct hci_dev {
struct rfkill *rfkill;
struct module *owner;
unsigned long dev_flags;
struct delayed_work le_scan_disable;
struct work_struct le_scan;
struct le_scan_params le_scan_params;
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb);
void (*destruct)(struct hci_dev *hdev);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
};
......@@ -270,11 +294,10 @@ struct hci_conn {
__u16 state;
__u8 mode;
__u8 type;
__u8 out;
bool out;
__u8 attempt;
__u8 dev_class[3];
__u8 features[8];
__u8 ssp_mode;
__u16 interval;
__u16 pkt_type;
__u16 link_policy;
......@@ -286,12 +309,10 @@ struct hci_conn {
__u8 pin_length;
__u8 enc_key_size;
__u8 io_capability;
__u8 power_save;
__u16 disc_timeout;
unsigned long pend;
unsigned long flags;
__u8 remote_cap;
__u8 remote_oob;
__u8 remote_auth;
unsigned int sent;
......@@ -348,21 +369,26 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
#define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */
static inline void inquiry_cache_init(struct hci_dev *hdev)
static inline void discovery_init(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
c->list = NULL;
hdev->discovery.state = DISCOVERY_STOPPED;
INIT_LIST_HEAD(&hdev->discovery.all);
INIT_LIST_HEAD(&hdev->discovery.unknown);
INIT_LIST_HEAD(&hdev->discovery.resolve);
}
bool hci_discovery_active(struct hci_dev *hdev);
void hci_discovery_set_state(struct hci_dev *hdev, int state);
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
return c->list == NULL;
return list_empty(&hdev->discovery.all);
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
{
struct inquiry_cache *c = &hdev->inq_cache;
struct discovery_state *c = &hdev->discovery;
return jiffies - c->timestamp;
}
......@@ -372,8 +398,16 @@ static inline long inquiry_entry_age(struct inquiry_entry *e)
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr);
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
bdaddr_t *bdaddr);
struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bdaddr_t *bdaddr);
struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
bdaddr_t *bdaddr,
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);
/* ----- HCI Connections ----- */
enum {
......@@ -384,8 +418,19 @@ enum {
HCI_CONN_MODE_CHANGE_PEND,
HCI_CONN_SCO_SETUP_PEND,
HCI_CONN_LE_SMP_PEND,
HCI_CONN_MGMT_CONNECTED,
HCI_CONN_SSP_ENABLED,
HCI_CONN_POWER_SAVE,
HCI_CONN_REMOTE_OOB,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
return (test_bit(HCI_SSP_ENABLED, &hdev->flags) &&
test_bit(HCI_CONN_SSP_ENABLED, &conn->flags));
}
static inline void hci_conn_hash_init(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
......@@ -566,36 +611,33 @@ static inline void hci_conn_put(struct hci_conn *conn)
}
/* ----- HCI Devices ----- */
static inline void __hci_dev_put(struct hci_dev *d)
static inline void hci_dev_put(struct hci_dev *d)
{
if (atomic_dec_and_test(&d->refcnt))
d->destruct(d);
put_device(&d->dev);
}
/*
* hci_dev_put and hci_dev_hold are macros to avoid dragging all the
* overhead of all the modular infrastructure into this header.
*/
#define hci_dev_put(d) \
do { \
__hci_dev_put(d); \
module_put(d->owner); \
} while (0)
static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
{
atomic_inc(&d->refcnt);
get_device(&d->dev);
return d;
}
#define hci_dev_hold(d) \
({ \
try_module_get(d->owner) ? __hci_dev_hold(d) : NULL; \
})
#define hci_dev_lock(d) mutex_lock(&d->lock)
#define hci_dev_unlock(d) mutex_unlock(&d->lock)
#define to_hci_dev(d) container_of(d, struct hci_dev, dev)
#define to_hci_conn(c) container_of(c, struct hci_conn, dev)
static inline void *hci_get_drvdata(struct hci_dev *hdev)
{
return dev_get_drvdata(&hdev->dev);
}
static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
{
dev_set_drvdata(&hdev->dev, data);
}
struct hci_dev *hci_dev_get(int index);
struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
......@@ -619,20 +661,23 @@ int hci_inquiry(void __user *arg);
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_blacklist_clear(struct hci_dev *hdev);
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr);
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);
int hci_uuids_clear(struct hci_dev *hdev);
int 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_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type);
int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16 ediv,
u8 rand[8]);
struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 addr_type);
int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
......@@ -674,6 +719,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)
#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR))
/* ----- Extended LMP capabilities ----- */
#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE)
......@@ -755,7 +801,7 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
if (conn->type != ACL_LINK && conn->type != LE_LINK)
return;
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
......@@ -796,7 +842,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
hci_proto_auth_cfm(conn, status);
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
......@@ -859,25 +905,71 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
read_unlock(&hci_cb_list_lock);
}
static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
{
u8 field_len;
size_t parsed;
for (parsed = 0; parsed < data_len - 1; parsed += field_len) {
field_len = data[0];
if (field_len == 0)
break;
parsed += field_len + 1;
if (parsed > data_len)
break;
if (data[1] == type)
return true;
data += field_len + 1;
}
return false;
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len)
{
eir[eir_len++] = sizeof(type) + data_len;
eir[eir_len++] = type;
memcpy(&eir[eir_len], data, data_len);
eir_len += data_len;
return eir_len;
}
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);
int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
/* ----- HCI Sockets ----- */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
struct sock *skip_sk);
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk);
void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb);
void hci_sock_dev_event(struct hci_dev *hdev, int event);
/* Management interface */
#define MGMT_ADDR_BREDR 0x00
#define MGMT_ADDR_LE_PUBLIC 0x01
#define MGMT_ADDR_LE_RANDOM 0x02
#define MGMT_ADDR_INVALID 0xff
#define DISCOV_TYPE_BREDR (BIT(MGMT_ADDR_BREDR))
#define DISCOV_TYPE_LE (BIT(MGMT_ADDR_LE_PUBLIC) | \
BIT(MGMT_ADDR_LE_RANDOM))
#define DISCOV_TYPE_INTERLEAVED (BIT(MGMT_ADDR_BREDR) | \
BIT(MGMT_ADDR_LE_PUBLIC) | \
BIT(MGMT_ADDR_LE_RANDOM))
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_index_added(struct hci_dev *hdev);
int mgmt_index_removed(struct hci_dev *hdev);
......@@ -886,56 +978,67 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
u8 persistent);
int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type);
int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type);
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
u8 persistent);
int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u32 flags, u8 *name, u8 name_len,
u8 *dev_class);
int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type);
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status);
u8 addr_type, u8 status);
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status);
u8 status);
int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status);
u8 status);
int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
__le32 value, u8 confirm_hint);
u8 link_type, u8 addr_type, __le32 value,
u8 confirm_hint);
int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status);
int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 status);
int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr);
u8 link_type, u8 addr_type, u8 status);
int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);
int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type);
int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status);
int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 status);
int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
u8 link_type, u8 addr_type, u8 status);
int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);
int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status);
int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status);
int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
u8 *randomizer, u8 status);
u8 *randomizer, u8 status);
int mgmt_le_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
int mgmt_interleaved_discovery(struct hci_dev *hdev);
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);
int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
/* HCI socket flags */
#define HCI_PI_MGMT_INIT 0
struct hci_pinfo {
struct bt_sock bt;
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
unsigned short channel;
unsigned long flags;
};
/* HCI security filter */
......@@ -966,5 +1069,7 @@ void hci_le_ltk_neg_reply(struct hci_conn *conn);
int hci_do_inquiry(struct hci_dev *hdev, u8 length);
int hci_cancel_inquiry(struct hci_dev *hdev);
int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
int timeout);
#endif /* __HCI_CORE_H */
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2011-2012 Intel Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
#ifndef __HCI_MON_H
#define __HCI_MON_H
struct hci_mon_hdr {
__le16 opcode;
__le16 index;
__le16 len;
} __packed;
#define HCI_MON_HDR_SIZE 6
#define HCI_MON_NEW_INDEX 0
#define HCI_MON_DEL_INDEX 1
#define HCI_MON_COMMAND_PKT 2
#define HCI_MON_EVENT_PKT 3
#define HCI_MON_ACL_TX_PKT 4
#define HCI_MON_ACL_RX_PKT 5
#define HCI_MON_SCO_TX_PKT 6
#define HCI_MON_SCO_RX_PKT 7
struct hci_mon_new_index {
__u8 type;
__u8 bus;
bdaddr_t bdaddr;
char name[8];
} __packed;
#define HCI_MON_NEW_INDEX_SIZE 16
#endif /* __HCI_MON_H */
......@@ -45,11 +45,11 @@
#define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF
#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF
#define L2CAP_DISC_TIMEOUT (100)
#define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */
#define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100)
#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000)
#define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000)
#define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000)
#define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000)
/* L2CAP socket address */
struct sockaddr_l2 {
......@@ -492,51 +492,56 @@ struct l2cap_chan {
struct sk_buff_head srej_q;
struct list_head srej_l;
struct list_head list;
struct list_head global_l;
struct list_head list;
struct list_head global_l;
void *data;
struct l2cap_ops *ops;
void *data;
struct l2cap_ops *ops;
struct mutex lock;
};
struct l2cap_ops {
char *name;
char *name;
struct l2cap_chan *(*new_connection) (void *data);
int (*recv) (void *data, struct sk_buff *skb);
void (*close) (void *data);
void (*state_change) (void *data, int state);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb, int *err);
};
struct l2cap_conn {
struct hci_conn *hcon;
struct hci_chan *hchan;
struct hci_conn *hcon;
struct hci_chan *hchan;
bdaddr_t *dst;
bdaddr_t *src;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu;
unsigned int mtu;
__u32 feat_mask;
__u32 feat_mask;
__u8 fixed_chan_mask;
__u8 info_state;
__u8 info_ident;
__u8 info_state;
__u8 info_ident;
struct delayed_work info_timer;
struct delayed_work info_timer;
spinlock_t lock;
spinlock_t lock;
struct sk_buff *rx_skb;
__u32 rx_len;
__u8 tx_ident;
struct sk_buff *rx_skb;
__u32 rx_len;
__u8 tx_ident;
__u8 disc_reason;
__u8 disc_reason;
struct delayed_work security_timer;
struct smp_chan *smp_chan;
struct delayed_work security_timer;
struct smp_chan *smp_chan;
struct list_head chan_l;
struct mutex chan_lock;
struct list_head chan_l;
struct mutex chan_lock;
};
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
......@@ -551,9 +556,9 @@ struct l2cap_conn {
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
struct l2cap_pinfo {
struct bt_sock bt;
struct bt_sock bt;
struct l2cap_chan *chan;
struct sk_buff *rx_busy_skb;
struct sk_buff *rx_busy_skb;
};
enum {
......@@ -606,21 +611,37 @@ static inline void l2cap_chan_put(struct l2cap_chan *c)
kfree(c);
}
static inline void l2cap_chan_lock(struct l2cap_chan *chan)
{
mutex_lock(&chan->lock);
}
static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
{
mutex_unlock(&chan->lock);
}
static inline void l2cap_set_timer(struct l2cap_chan *chan,
struct delayed_work *work, long timeout)
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
BT_DBG("chan %p state %s timeout %ld", chan,
state_to_string(chan->state), timeout);
if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
static inline void l2cap_clear_timer(struct l2cap_chan *chan,
static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
struct delayed_work *work)
{
if (cancel_delayed_work(work))
bool ret;
ret = cancel_delayed_work(work);
if (ret)
l2cap_chan_put(chan);
return ret;
}
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
......
......@@ -2,6 +2,7 @@
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2010 Nokia Corporation
Copyright (C) 2011-2012 Intel Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
......@@ -39,29 +40,47 @@
#define MGMT_STATUS_INVALID_PARAMS 0x0d
#define MGMT_STATUS_DISCONNECTED 0x0e
#define MGMT_STATUS_NOT_POWERED 0x0f
#define MGMT_STATUS_CANCELLED 0x10
#define MGMT_STATUS_INVALID_INDEX 0x11
struct mgmt_hdr {
__le16 opcode;
__le16 index;
__le16 len;
__le16 opcode;
__le16 index;
__le16 len;
} __packed;
struct mgmt_addr_info {
bdaddr_t bdaddr;
__u8 type;
} __packed;
#define MGMT_ADDR_INFO_SIZE 7
#define MGMT_OP_READ_VERSION 0x0001
#define MGMT_READ_VERSION_SIZE 0
struct mgmt_rp_read_version {
__u8 version;
__le16 revision;
__u8 version;
__le16 revision;
} __packed;
#define MGMT_OP_READ_COMMANDS 0x0002
#define MGMT_READ_COMMANDS_SIZE 0
struct mgmt_rp_read_commands {
__le16 num_commands;
__le16 num_events;
__le16 opcodes[0];
} __packed;
#define MGMT_OP_READ_INDEX_LIST 0x0003
#define MGMT_READ_INDEX_LIST_SIZE 0
struct mgmt_rp_read_index_list {
__le16 num_controllers;
__le16 index[0];
__le16 num_controllers;
__le16 index[0];
} __packed;
/* Reserve one extra byte for names in management messages so that they
* are always guaranteed to be nul-terminated */
#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1)
#define MGMT_MAX_SHORT_NAME_LENGTH (10 + 1)
#define MGMT_MAX_SHORT_NAME_LENGTH (HCI_MAX_SHORT_NAME_LENGTH + 1)
#define MGMT_SETTING_POWERED 0x00000001
#define MGMT_SETTING_CONNECTABLE 0x00000002
......@@ -75,28 +94,32 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_LE 0x00000200
#define MGMT_OP_READ_INFO 0x0004
#define MGMT_READ_INFO_SIZE 0
struct mgmt_rp_read_info {
bdaddr_t bdaddr;
__u8 version;
__le16 manufacturer;
__le32 supported_settings;
__le32 current_settings;
__u8 dev_class[3];
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH];
bdaddr_t bdaddr;
__u8 version;
__le16 manufacturer;
__le32 supported_settings;
__le32 current_settings;
__u8 dev_class[3];
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH];
} __packed;
struct mgmt_mode {
__u8 val;
} __packed;
#define MGMT_SETTING_SIZE 1
#define MGMT_OP_SET_POWERED 0x0005
#define MGMT_OP_SET_DISCOVERABLE 0x0006
struct mgmt_cp_set_discoverable {
__u8 val;
__u16 timeout;
__u8 val;
__u16 timeout;
} __packed;
#define MGMT_SET_DISCOVERABLE_SIZE 3
#define MGMT_OP_SET_CONNECTABLE 0x0007
......@@ -111,73 +134,76 @@ struct mgmt_cp_set_discoverable {
#define MGMT_OP_SET_HS 0x000C
#define MGMT_OP_SET_LE 0x000D
#define MGMT_OP_SET_DEV_CLASS 0x000E
struct mgmt_cp_set_dev_class {
__u8 major;
__u8 minor;
__u8 major;
__u8 minor;
} __packed;
#define MGMT_SET_DEV_CLASS_SIZE 2
#define MGMT_OP_SET_LOCAL_NAME 0x000F
struct mgmt_cp_set_local_name {
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH];
} __packed;
#define MGMT_SET_LOCAL_NAME_SIZE 260
#define MGMT_OP_ADD_UUID 0x0010
struct mgmt_cp_add_uuid {
__u8 uuid[16];
__u8 svc_hint;
__u8 uuid[16];
__u8 svc_hint;
} __packed;
#define MGMT_ADD_UUID_SIZE 17
#define MGMT_OP_REMOVE_UUID 0x0011
struct mgmt_cp_remove_uuid {
__u8 uuid[16];
__u8 uuid[16];
} __packed;
#define MGMT_REMOVE_UUID_SIZE 16
struct mgmt_link_key_info {
bdaddr_t bdaddr;
u8 type;
u8 val[16];
u8 pin_len;
struct mgmt_addr_info addr;
__u8 type;
__u8 val[16];
__u8 pin_len;
} __packed;
#define MGMT_OP_LOAD_LINK_KEYS 0x0012
struct mgmt_cp_load_link_keys {
__u8 debug_keys;
__le16 key_count;
struct mgmt_link_key_info keys[0];
__u8 debug_keys;
__le16 key_count;
struct mgmt_link_key_info keys[0];
} __packed;
#define MGMT_LOAD_LINK_KEYS_SIZE 3
#define MGMT_OP_REMOVE_KEYS 0x0013
struct mgmt_cp_remove_keys {
bdaddr_t bdaddr;
__u8 disconnect;
struct mgmt_ltk_info {
struct mgmt_addr_info addr;
__u8 authenticated;
__u8 master;
__u8 enc_size;
__le16 ediv;
__u8 rand[8];
__u8 val[16];
} __packed;
struct mgmt_rp_remove_keys {
bdaddr_t bdaddr;
__u8 status;
};
#define MGMT_OP_LOAD_LONG_TERM_KEYS 0x0013
struct mgmt_cp_load_long_term_keys {
__le16 key_count;
struct mgmt_ltk_info keys[0];
} __packed;
#define MGMT_LOAD_LONG_TERM_KEYS_SIZE 2
#define MGMT_OP_DISCONNECT 0x0014
struct mgmt_cp_disconnect {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_DISCONNECT_SIZE MGMT_ADDR_INFO_SIZE
struct mgmt_rp_disconnect {
bdaddr_t bdaddr;
__u8 status;
} __packed;
#define MGMT_ADDR_BREDR 0x00
#define MGMT_ADDR_LE_PUBLIC 0x01
#define MGMT_ADDR_LE_RANDOM 0x02
#define MGMT_ADDR_INVALID 0xff
struct mgmt_addr_info {
bdaddr_t bdaddr;
__u8 type;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_GET_CONNECTIONS 0x0015
#define MGMT_GET_CONNECTIONS_SIZE 0
struct mgmt_rp_get_connections {
__le16 conn_count;
struct mgmt_addr_info addr[0];
......@@ -185,124 +211,152 @@ struct mgmt_rp_get_connections {
#define MGMT_OP_PIN_CODE_REPLY 0x0016
struct mgmt_cp_pin_code_reply {
bdaddr_t bdaddr;
__u8 pin_len;
__u8 pin_code[16];
struct mgmt_addr_info addr;
__u8 pin_len;
__u8 pin_code[16];
} __packed;
#define MGMT_PIN_CODE_REPLY_SIZE (MGMT_ADDR_INFO_SIZE + 17)
struct mgmt_rp_pin_code_reply {
bdaddr_t bdaddr;
uint8_t status;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017
struct mgmt_cp_pin_code_neg_reply {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_PIN_CODE_NEG_REPLY_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_SET_IO_CAPABILITY 0x0018
struct mgmt_cp_set_io_capability {
__u8 io_capability;
__u8 io_capability;
} __packed;
#define MGMT_SET_IO_CAPABILITY_SIZE 1
#define MGMT_OP_PAIR_DEVICE 0x0019
struct mgmt_cp_pair_device {
struct mgmt_addr_info addr;
__u8 io_cap;
__u8 io_cap;
} __packed;
#define MGMT_PAIR_DEVICE_SIZE (MGMT_ADDR_INFO_SIZE + 1)
struct mgmt_rp_pair_device {
struct mgmt_addr_info addr;
__u8 status;
} __packed;
#define MGMT_OP_USER_CONFIRM_REPLY 0x001A
#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001A
#define MGMT_CANCEL_PAIR_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_UNPAIR_DEVICE 0x001B
struct mgmt_cp_unpair_device {
struct mgmt_addr_info addr;
__u8 disconnect;
} __packed;
#define MGMT_UNPAIR_DEVICE_SIZE (MGMT_ADDR_INFO_SIZE + 1)
struct mgmt_rp_unpair_device {
struct mgmt_addr_info addr;
};
#define MGMT_OP_USER_CONFIRM_REPLY 0x001C
struct mgmt_cp_user_confirm_reply {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_USER_CONFIRM_REPLY_SIZE MGMT_ADDR_INFO_SIZE
struct mgmt_rp_user_confirm_reply {
bdaddr_t bdaddr;
__u8 status;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001B
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001D
struct mgmt_cp_user_confirm_neg_reply {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_USER_CONFIRM_NEG_REPLY_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_USER_PASSKEY_REPLY 0x001C
#define MGMT_OP_USER_PASSKEY_REPLY 0x001E
struct mgmt_cp_user_passkey_reply {
bdaddr_t bdaddr;
__le32 passkey;
struct mgmt_addr_info addr;
__le32 passkey;
} __packed;
#define MGMT_USER_PASSKEY_REPLY_SIZE (MGMT_ADDR_INFO_SIZE + 4)
struct mgmt_rp_user_passkey_reply {
bdaddr_t bdaddr;
__u8 status;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001D
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001F
struct mgmt_cp_user_passkey_neg_reply {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_USER_PASSKEY_NEG_REPLY_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x001E
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020
#define MGMT_READ_LOCAL_OOB_DATA_SIZE 0
struct mgmt_rp_read_local_oob_data {
__u8 hash[16];
__u8 randomizer[16];
__u8 hash[16];
__u8 randomizer[16];
} __packed;
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x001F
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0021
struct mgmt_cp_add_remote_oob_data {
bdaddr_t bdaddr;
__u8 hash[16];
__u8 randomizer[16];
struct mgmt_addr_info addr;
__u8 hash[16];
__u8 randomizer[16];
} __packed;
#define MGMT_ADD_REMOTE_OOB_DATA_SIZE (MGMT_ADDR_INFO_SIZE + 32)
#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0020
#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0022
struct mgmt_cp_remove_remote_oob_data {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_REMOVE_REMOTE_OOB_DATA_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_START_DISCOVERY 0x0021
#define MGMT_OP_START_DISCOVERY 0x0023
struct mgmt_cp_start_discovery {
__u8 type;
} __packed;
#define MGMT_START_DISCOVERY_SIZE 1
#define MGMT_OP_STOP_DISCOVERY 0x0022
#define MGMT_OP_STOP_DISCOVERY 0x0024
struct mgmt_cp_stop_discovery {
__u8 type;
} __packed;
#define MGMT_STOP_DISCOVERY_SIZE 1
#define MGMT_OP_CONFIRM_NAME 0x0023
#define MGMT_OP_CONFIRM_NAME 0x0025
struct mgmt_cp_confirm_name {
bdaddr_t bdaddr;
__u8 name_known;
struct mgmt_addr_info addr;
__u8 name_known;
} __packed;
#define MGMT_CONFIRM_NAME_SIZE (MGMT_ADDR_INFO_SIZE + 1)
struct mgmt_rp_confirm_name {
bdaddr_t bdaddr;
__u8 status;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_OP_BLOCK_DEVICE 0x0024
#define MGMT_OP_BLOCK_DEVICE 0x0026
struct mgmt_cp_block_device {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_BLOCK_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_OP_UNBLOCK_DEVICE 0x0025
#define MGMT_OP_UNBLOCK_DEVICE 0x0027
struct mgmt_cp_unblock_device {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_UNBLOCK_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
__u8 data[0];
__le16 opcode;
__u8 status;
__u8 data[0];
} __packed;
#define MGMT_EV_CMD_STATUS 0x0002
struct mgmt_ev_cmd_status {
__u8 status;
__le16 opcode;
__le16 opcode;
__u8 status;
} __packed;
#define MGMT_EV_CONTROLLER_ERROR 0x0003
struct mgmt_ev_controller_error {
__u8 error_code;
__u8 error_code;
} __packed;
#define MGMT_EV_INDEX_ADDED 0x0004
......@@ -313,78 +367,96 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_CLASS_OF_DEV_CHANGED 0x0007
struct mgmt_ev_class_of_dev_changed {
__u8 dev_class[3];
__u8 dev_class[3];
};
#define MGMT_EV_LOCAL_NAME_CHANGED 0x0008
struct mgmt_ev_local_name_changed {
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH];
__u8 name[MGMT_MAX_NAME_LENGTH];
__u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH];
} __packed;
#define MGMT_EV_NEW_LINK_KEY 0x0009
struct mgmt_ev_new_link_key {
__u8 store_hint;
__u8 store_hint;
struct mgmt_link_key_info key;
} __packed;
#define MGMT_EV_CONNECTED 0x000A
#define MGMT_EV_NEW_LONG_TERM_KEY 0x000A
struct mgmt_ev_new_long_term_key {
__u8 store_hint;
struct mgmt_ltk_info key;
} __packed;
#define MGMT_EV_DISCONNECTED 0x000B
#define MGMT_EV_DEVICE_CONNECTED 0x000B
struct mgmt_ev_device_connected {
struct mgmt_addr_info addr;
__le32 flags;
__le16 eir_len;
__u8 eir[0];
} __packed;
#define MGMT_EV_DEVICE_DISCONNECTED 0x000C
#define MGMT_EV_CONNECT_FAILED 0x000C
#define MGMT_EV_CONNECT_FAILED 0x000D
struct mgmt_ev_connect_failed {
struct mgmt_addr_info addr;
__u8 status;
__u8 status;
} __packed;
#define MGMT_EV_PIN_CODE_REQUEST 0x000D
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
bdaddr_t bdaddr;
__u8 secure;
struct mgmt_addr_info addr;
__u8 secure;
} __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000E
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
__u8 confirm_hint;
__le32 value;
struct mgmt_addr_info addr;
__u8 confirm_hint;
__le32 value;
} __packed;
#define MGMT_EV_USER_PASSKEY_REQUEST 0x000F
#define MGMT_EV_USER_PASSKEY_REQUEST 0x0010
struct mgmt_ev_user_passkey_request {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_AUTH_FAILED 0x0010
#define MGMT_EV_AUTH_FAILED 0x0011
struct mgmt_ev_auth_failed {
bdaddr_t bdaddr;
__u8 status;
struct mgmt_addr_info addr;
__u8 status;
} __packed;
#define MGMT_EV_DEVICE_FOUND 0x0011
#define MGMT_DEV_FOUND_CONFIRM_NAME 0x01
#define MGMT_DEV_FOUND_LEGACY_PAIRING 0x02
#define MGMT_EV_DEVICE_FOUND 0x0012
struct mgmt_ev_device_found {
struct mgmt_addr_info addr;
__u8 dev_class[3];
__s8 rssi;
__u8 confirm_name;
__u8 eir[HCI_MAX_EIR_LENGTH];
} __packed;
#define MGMT_EV_REMOTE_NAME 0x0012
struct mgmt_ev_remote_name {
bdaddr_t bdaddr;
__u8 name[MGMT_MAX_NAME_LENGTH];
__s8 rssi;
__u8 flags[4];
__le16 eir_len;
__u8 eir[0];
} __packed;
#define MGMT_EV_DISCOVERING 0x0013
struct mgmt_ev_discovering {
__u8 type;
__u8 discovering;
} __packed;
#define MGMT_EV_DEVICE_BLOCKED 0x0014
struct mgmt_ev_device_blocked {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_DEVICE_UNBLOCKED 0x0015
struct mgmt_ev_device_unblocked {
bdaddr_t bdaddr;
struct mgmt_addr_info addr;
} __packed;
#define MGMT_EV_DEVICE_UNPAIRED 0x0016
struct mgmt_ev_device_unpaired {
struct mgmt_addr_info addr;
} __packed;
......@@ -127,7 +127,7 @@ struct smp_chan {
u8 rrnd[16]; /* SMP Pairing Random (remote) */
u8 pcnf[16]; /* SMP Pairing Confirm */
u8 tk[16]; /* SMP Temporary Key */
u8 smp_key_size;
u8 enc_key_size;
unsigned long smp_flags;
struct crypto_blkcipher *tfm;
struct work_struct confirm;
......
......@@ -29,7 +29,6 @@ menuconfig BT
BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CAPI Message Transport Protocol)
HIDP Module (Human Interface Device Protocol)
SMP Module (Security Manager Protocol)
Say Y here to compile Bluetooth support into the kernel or say M to
compile it as module (bluetooth).
......
......@@ -143,10 +143,10 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == BNEPGETCONNLIST) {
struct bnep_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
......@@ -157,7 +157,7 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = bnep_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;
......
......@@ -137,10 +137,10 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == CMTPGETCONNLIST) {
struct cmtp_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
......@@ -151,7 +151,7 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = cmtp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;
......
......@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>
#include <asm/system.h>
......@@ -51,7 +50,7 @@ static void hci_le_connect(struct hci_conn *conn)
struct hci_cp_le_create_conn cp;
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
......@@ -80,10 +79,10 @@ void hci_acl_connect(struct hci_conn *conn)
struct inquiry_entry *ie;
struct hci_cp_create_conn cp;
BT_DBG("%p", conn);
BT_DBG("hcon %p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->link_mode = HCI_LM_MASTER;
......@@ -105,7 +104,8 @@ void hci_acl_connect(struct hci_conn *conn)
}
memcpy(conn->dev_class, ie->data.dev_class, 3);
conn->ssp_mode = ie->data.ssp_mode;
if (ie->data.ssp_mode > 0)
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
}
cp.pkt_type = cpu_to_le16(conn->pkt_type);
......@@ -151,7 +151,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
BT_DBG("%p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->attempt++;
......@@ -169,7 +169,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
BT_DBG("%p", conn);
conn->state = BT_CONNECT;
conn->out = 1;
conn->out = true;
conn->attempt++;
......@@ -279,16 +279,13 @@ static void hci_conn_timeout(struct work_struct *work)
{
struct hci_conn *conn = container_of(work, struct hci_conn,
disc_work.work);
struct hci_dev *hdev = conn->hdev;
__u8 reason;
BT_DBG("conn %p state %d", conn, conn->state);
BT_DBG("conn %p state %s", conn, state_to_string(conn->state));
if (atomic_read(&conn->refcnt))
return;
hci_dev_lock(hdev);
switch (conn->state) {
case BT_CONNECT:
case BT_CONNECT2:
......@@ -308,8 +305,6 @@ static void hci_conn_timeout(struct work_struct *work)
conn->state = BT_CLOSED;
break;
}
hci_dev_unlock(hdev);
}
/* Enter sniff mode */
......@@ -337,7 +332,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn)
hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
}
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
struct hci_cp_sniff_mode cp;
cp.handle = cpu_to_le16(conn->handle);
cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
......@@ -372,7 +367,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
BT_DBG("%s dst %s", hdev->name, batostr(dst));
conn = kzalloc(sizeof(struct hci_conn), GFP_ATOMIC);
conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
if (!conn)
return NULL;
......@@ -386,7 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->remote_auth = 0xff;
conn->key_type = 0xff;
conn->power_save = 1;
set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
switch (type) {
......@@ -407,7 +402,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
skb_queue_head_init(&conn->data_q);
INIT_LIST_HEAD(&conn->chan_list);;
INIT_LIST_HEAD(&conn->chan_list);
INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
......@@ -555,7 +550,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (!acl) {
acl = hci_conn_add(hdev, ACL_LINK, dst);
if (!acl)
return NULL;
return ERR_PTR(-ENOMEM);
}
hci_conn_hold(acl);
......@@ -575,7 +570,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
sco = hci_conn_add(hdev, type, dst);
if (!sco) {
hci_conn_put(acl);
return NULL;
return ERR_PTR(-ENOMEM);
}
}
......@@ -586,12 +581,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (acl->state == BT_CONNECTED &&
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
acl->power_save = 1;
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON);
if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->flags)) {
/* defer SCO setup until mode change completed */
set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->pend);
set_bit(HCI_CONN_SCO_SETUP_PEND, &acl->flags);
return sco;
}
......@@ -607,8 +602,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
!(conn->link_mode & HCI_LM_ENCRYPT))
if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
return 0;
return 1;
......@@ -633,17 +627,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
conn->auth_type = auth_type;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp;
/* encrypt must be pending if auth is also pending */
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp);
if (conn->key_type != 0xff)
set_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
}
return 0;
......@@ -654,7 +648,7 @@ static void hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 0x01;
......@@ -674,8 +668,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* For non 2.1 devices and low security level we don't need the link
key. */
if (sec_level == BT_SECURITY_LOW &&
(!conn->ssp_mode || !conn->hdev->ssp_mode))
if (sec_level == BT_SECURITY_LOW && !hci_conn_ssp_enabled(conn))
return 1;
/* For other security levels we need the link key. */
......@@ -704,7 +697,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
goto encrypt;
auth:
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return 0;
if (!hci_conn_auth(conn, sec_level, auth_type))
......@@ -739,7 +732,7 @@ int hci_conn_change_link_key(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_change_conn_link_key cp;
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
......@@ -758,7 +751,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
if (!role && conn->link_mode & HCI_LM_MASTER)
return 1;
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->flags)) {
struct hci_cp_switch_role cp;
bacpy(&cp.bdaddr, &conn->dst);
cp.role = role;
......@@ -782,10 +775,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
if (conn->mode != HCI_CM_SNIFF)
goto timer;
if (!conn->power_save && !force_active)
if (!test_bit(HCI_CONN_POWER_SAVE, &conn->flags) && !force_active)
goto timer;
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
struct hci_cp_exit_sniff_mode cp;
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
......@@ -801,11 +794,11 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
void hci_conn_hash_flush(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
struct hci_conn *c, *n;
BT_DBG("hdev %s", hdev->name);
list_for_each_entry_rcu(c, &h->list, list) {
list_for_each_entry_safe(c, n, &h->list, list) {
c->state = BT_CLOSED;
hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM);
......@@ -950,7 +943,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
BT_DBG("%s conn %p", hdev->name, conn);
chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC);
chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL);
if (!chan)
return NULL;
......@@ -981,10 +974,10 @@ int hci_chan_del(struct hci_chan *chan)
void hci_chan_list_flush(struct hci_conn *conn)
{
struct hci_chan *chan;
struct hci_chan *chan, *n;
BT_DBG("conn %p", conn);
list_for_each_entry_rcu(chan, &conn->chan_list, list)
list_for_each_entry_safe(chan, n, &conn->chan_list, list)
hci_chan_del(chan);
}
......@@ -40,7 +40,6 @@
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <linux/timer.h>
#include <linux/crypto.h>
......@@ -55,8 +54,6 @@
#define AUTO_OFF_TIMEOUT 2000
bool enable_hs;
static void hci_rx_work(struct work_struct *work);
static void hci_cmd_work(struct work_struct *work);
static void hci_tx_work(struct work_struct *work);
......@@ -69,24 +66,11 @@ DEFINE_RWLOCK(hci_dev_list_lock);
LIST_HEAD(hci_cb_list);
DEFINE_RWLOCK(hci_cb_list_lock);
/* HCI notifiers list */
static ATOMIC_NOTIFIER_HEAD(hci_notifier);
/* ---- HCI notifications ---- */
int hci_register_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&hci_notifier, nb);
}
int hci_unregister_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&hci_notifier, nb);
}
static void hci_notify(struct hci_dev *hdev, int event)
{
atomic_notifier_call_chain(&hci_notifier, event, hdev);
hci_sock_dev_event(hdev, event);
}
/* ---- HCI requests ---- */
......@@ -98,8 +82,28 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
/* If this is the init phase check if the completed command matches
* the last init command, and if not just return.
*/
if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
struct sk_buff *skb;
/* Some CSR based controllers generate a spontaneous
* reset complete event during init and any pending
* command will never be completed. In such a case we
* need to resend whatever was the last sent
* command.
*/
if (cmd != HCI_OP_RESET || sent->opcode == HCI_OP_RESET)
return;
skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
if (skb) {
skb_queue_head(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);
}
return;
}
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
......@@ -355,72 +359,209 @@ struct hci_dev *hci_dev_get(int index)
}
/* ---- Inquiry support ---- */
static void inquiry_cache_flush(struct hci_dev *hdev)
bool hci_discovery_active(struct hci_dev *hdev)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *next = cache->list, *e;
struct discovery_state *discov = &hdev->discovery;
switch (discov->state) {
case DISCOVERY_FINDING:
case DISCOVERY_RESOLVING:
return true;
default:
return false;
}
}
void hci_discovery_set_state(struct hci_dev *hdev, int state)
{
BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
if (hdev->discovery.state == state)
return;
switch (state) {
case DISCOVERY_STOPPED:
if (hdev->discovery.state != DISCOVERY_STARTING)
mgmt_discovering(hdev, 0);
hdev->discovery.type = 0;
break;
case DISCOVERY_STARTING:
break;
case DISCOVERY_FINDING:
mgmt_discovering(hdev, 1);
break;
case DISCOVERY_RESOLVING:
break;
case DISCOVERY_STOPPING:
break;
}
hdev->discovery.state = state;
}
BT_DBG("cache %p", cache);
static void inquiry_cache_flush(struct hci_dev *hdev)
{
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *p, *n;
cache->list = NULL;
while ((e = next)) {
next = e->next;
kfree(e);
list_for_each_entry_safe(p, n, &cache->all, all) {
list_del(&p->all);
kfree(p);
}
INIT_LIST_HEAD(&cache->unknown);
INIT_LIST_HEAD(&cache->resolve);
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
for (e = cache->list; e; e = e->next)
list_for_each_entry(e, &cache->all, all) {
if (!bacmp(&e->data.bdaddr, bdaddr))
return e;
}
return NULL;
}
struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bdaddr_t *bdaddr)
{
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
list_for_each_entry(e, &cache->unknown, list) {
if (!bacmp(&e->data.bdaddr, bdaddr))
return e;
}
return NULL;
}
struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
bdaddr_t *bdaddr,
int state)
{
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
list_for_each_entry(e, &cache->resolve, list) {
if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
return e;
if (!bacmp(&e->data.bdaddr, bdaddr))
return e;
}
return NULL;
}
void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
struct inquiry_entry *ie)
{
struct discovery_state *cache = &hdev->discovery;
struct list_head *pos = &cache->resolve;
struct inquiry_entry *p;
list_del(&ie->list);
list_for_each_entry(p, &cache->resolve, list) {
if (p->name_state != NAME_PENDING &&
abs(p->data.rssi) >= abs(ie->data.rssi))
break;
return e;
pos = &p->list;
}
list_add(&ie->list, pos);
}
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known, bool *ssp)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *ie;
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
if (ssp)
*ssp = data->ssp_mode;
ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
if (!ie) {
/* Entry not in the cache. Add new one. */
ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
if (!ie)
return;
if (ie) {
if (ie->data.ssp_mode && ssp)
*ssp = true;
if (ie->name_state == NAME_NEEDED &&
data->rssi != ie->data.rssi) {
ie->data.rssi = data->rssi;
hci_inquiry_cache_update_resolve(hdev, ie);
}
ie->next = cache->list;
cache->list = ie;
goto update;
}
/* Entry not in the cache. Add new one. */
ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
if (!ie)
return false;
list_add(&ie->all, &cache->all);
if (name_known) {
ie->name_state = NAME_KNOWN;
} else {
ie->name_state = NAME_NOT_KNOWN;
list_add(&ie->list, &cache->unknown);
}
update:
if (name_known && ie->name_state != NAME_KNOWN &&
ie->name_state != NAME_PENDING) {
ie->name_state = NAME_KNOWN;
list_del(&ie->list);
}
memcpy(&ie->data, data, sizeof(*data));
ie->timestamp = jiffies;
cache->timestamp = jiffies;
if (ie->name_state == NAME_NOT_KNOWN)
return false;
return true;
}
static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct discovery_state *cache = &hdev->discovery;
struct inquiry_info *info = (struct inquiry_info *) buf;
struct inquiry_entry *e;
int copied = 0;
for (e = cache->list; e && copied < num; e = e->next, copied++) {
list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
if (copied >= num)
break;
bacpy(&info->bdaddr, &data->bdaddr);
info->pscan_rep_mode = data->pscan_rep_mode;
info->pscan_period_mode = data->pscan_period_mode;
info->pscan_mode = data->pscan_mode;
memcpy(info->dev_class, data->dev_class, 3);
info->clock_offset = data->clock_offset;
info++;
copied++;
}
BT_DBG("cache %p, copied %d", cache, copied);
......@@ -567,7 +708,7 @@ int hci_dev_open(__u16 dev)
hci_dev_hold(hdev);
set_bit(HCI_UP, &hdev->flags);
hci_notify(hdev, HCI_DEV_UP);
if (!test_bit(HCI_SETUP, &hdev->flags)) {
if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
hci_dev_lock(hdev);
mgmt_powered(hdev, 1);
hci_dev_unlock(hdev);
......@@ -603,6 +744,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
{
BT_DBG("%s %p", hdev->name, hdev);
cancel_work_sync(&hdev->le_scan);
hci_req_cancel(hdev, ENODEV);
hci_req_lock(hdev);
......@@ -619,14 +762,14 @@ static int hci_dev_do_close(struct hci_dev *hdev)
if (hdev->discov_timeout > 0) {
cancel_delayed_work(&hdev->discov_off);
hdev->discov_timeout = 0;
clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
}
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
cancel_delayed_work(&hdev->power_off);
if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags))
if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
cancel_delayed_work(&hdev->service_cache);
cancel_delayed_work_sync(&hdev->le_scan_disable);
hci_dev_lock(hdev);
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
......@@ -667,13 +810,18 @@ static int hci_dev_do_close(struct hci_dev *hdev)
* and no tasks are scheduled. */
hdev->close(hdev);
hci_dev_lock(hdev);
mgmt_powered(hdev, 0);
hci_dev_unlock(hdev);
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
hci_dev_lock(hdev);
mgmt_powered(hdev, 0);
hci_dev_unlock(hdev);
}
/* Clear flags */
hdev->flags = 0;
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
hci_req_unlock(hdev);
hci_dev_put(hdev);
......@@ -688,7 +836,12 @@ int hci_dev_close(__u16 dev)
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
cancel_delayed_work(&hdev->power_off);
err = hci_dev_do_close(hdev);
hci_dev_put(hdev);
return err;
}
......@@ -847,11 +1000,11 @@ int hci_get_dev_list(void __user *arg)
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list) {
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
cancel_delayed_work(&hdev->power_off);
if (!test_bit(HCI_MGMT, &hdev->flags))
set_bit(HCI_PAIRABLE, &hdev->flags);
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
set_bit(HCI_PAIRABLE, &hdev->dev_flags);
(dr + n)->dev_id = hdev->id;
(dr + n)->dev_opt = hdev->flags;
......@@ -883,11 +1036,11 @@ int hci_get_dev_info(void __user *arg)
if (!hdev)
return -ENODEV;
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
cancel_delayed_work_sync(&hdev->power_off);
if (!test_bit(HCI_MGMT, &hdev->flags))
set_bit(HCI_PAIRABLE, &hdev->flags);
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
set_bit(HCI_PAIRABLE, &hdev->dev_flags);
strcpy(di.name, hdev->name);
di.bdaddr = hdev->bdaddr;
......@@ -967,11 +1120,11 @@ static void hci_power_on(struct work_struct *work)
if (hci_dev_open(hdev->id) < 0)
return;
if (test_bit(HCI_AUTO_OFF, &hdev->flags))
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
schedule_delayed_work(&hdev->power_off,
msecs_to_jiffies(AUTO_OFF_TIMEOUT));
if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
mgmt_index_added(hdev);
}
......@@ -982,9 +1135,7 @@ static void hci_power_off(struct work_struct *work)
BT_DBG("%s", hdev->name);
clear_bit(HCI_AUTO_OFF, &hdev->flags);
hci_dev_close(hdev->id);
hci_dev_do_close(hdev);
}
static void hci_discov_off(struct work_struct *work)
......@@ -1037,6 +1188,18 @@ int hci_link_keys_clear(struct hci_dev *hdev)
return 0;
}
int hci_smp_ltks_clear(struct hci_dev *hdev)
{
struct smp_ltk *k, *tmp;
list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
list_del(&k->list);
kfree(k);
}
return 0;
}
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct link_key *k;
......@@ -1084,44 +1247,38 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
return 0;
}
struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
{
struct link_key *k;
struct smp_ltk *k;
list_for_each_entry(k, &hdev->link_keys, list) {
struct key_master_id *id;
if (k->type != HCI_LK_SMP_LTK)
list_for_each_entry(k, &hdev->long_term_keys, list) {
if (k->ediv != ediv ||
memcmp(rand, k->rand, sizeof(k->rand)))
continue;
if (k->dlen != sizeof(*id))
continue;
id = (void *) &k->data;
if (id->ediv == ediv &&
(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
return k;
return k;
}
return NULL;
}
EXPORT_SYMBOL(hci_find_ltk);
struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 type)
struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 addr_type)
{
struct link_key *k;
struct smp_ltk *k;
list_for_each_entry(k, &hdev->link_keys, list)
if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
list_for_each_entry(k, &hdev->long_term_keys, list)
if (addr_type == k->bdaddr_type &&
bacmp(bdaddr, &k->bdaddr) == 0)
return k;
return NULL;
}
EXPORT_SYMBOL(hci_find_link_key_type);
EXPORT_SYMBOL(hci_find_ltk_by_addr);
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)
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
u8 old_key_type, persistent;
......@@ -1175,40 +1332,39 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
return 0;
}
int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16
ediv, u8 rand[8])
{
struct link_key *key, *old_key;
struct key_master_id *id;
u8 old_key_type;
struct smp_ltk *key, *old_key;
BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
return 0;
old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
if (old_key) {
old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
if (old_key)
key = old_key;
old_key_type = old_key->type;
} else {
key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
else {
key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
list_add(&key->list, &hdev->link_keys);
old_key_type = 0xff;
list_add(&key->list, &hdev->long_term_keys);
}
key->dlen = sizeof(*id);
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, ltk, sizeof(key->val));
key->type = HCI_LK_SMP_LTK;
key->pin_len = key_size;
key->bdaddr_type = addr_type;
memcpy(key->val, tk, sizeof(key->val));
key->authenticated = authenticated;
key->ediv = ediv;
key->enc_size = enc_size;
key->type = type;
memcpy(key->rand, rand, sizeof(key->rand));
id = (void *) &key->data;
id->ediv = ediv;
memcpy(id->rand, rand, sizeof(id->rand));
if (!new_key)
return 0;
if (new_key)
mgmt_new_link_key(hdev, key, old_key_type);
if (type & HCI_SMP_LTK)
mgmt_new_ltk(hdev, key, 1);
return 0;
}
......@@ -1229,6 +1385,23 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return 0;
}
int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct smp_ltk *k, *tmp;
list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
if (bacmp(bdaddr, &k->bdaddr))
continue;
BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
list_del(&k->list);
kfree(k);
}
return 0;
}
/* HCI command timer function */
static void hci_cmd_timer(unsigned long arg)
{
......@@ -1240,7 +1413,7 @@ static void hci_cmd_timer(unsigned long arg)
}
struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
bdaddr_t *bdaddr)
bdaddr_t *bdaddr)
{
struct oob_data *data;
......@@ -1280,7 +1453,7 @@ int hci_remote_oob_data_clear(struct hci_dev *hdev)
}
int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
u8 *randomizer)
u8 *randomizer)
{
struct oob_data *data;
......@@ -1303,8 +1476,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
return 0;
}
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr)
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct bdaddr_list *b;
......@@ -1331,7 +1503,7 @@ int hci_blacklist_clear(struct hci_dev *hdev)
return 0;
}
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
......@@ -1349,10 +1521,10 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
list_add(&entry->list, &hdev->blacklist);
return mgmt_device_blocked(hdev, bdaddr);
return mgmt_device_blocked(hdev, bdaddr, type);
}
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
{
struct bdaddr_list *entry;
......@@ -1366,13 +1538,13 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
list_del(&entry->list);
kfree(entry);
return mgmt_device_unblocked(hdev, bdaddr);
return mgmt_device_unblocked(hdev, bdaddr, type);
}
static void hci_clear_adv_cache(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
adv_work.work);
adv_work.work);
hci_dev_lock(hdev);
......@@ -1415,11 +1587,7 @@ static inline int is_connectable_adv(u8 evt_type)
}
int hci_add_adv_entry(struct hci_dev *hdev,
struct hci_ev_le_advertising_info *ev)
{
struct adv_entry *entry;
if (!is_connectable_adv(ev->evt_type))
struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type))
return -EINVAL;
/* Only new entries should be added to adv_entries. So, if
......@@ -1427,7 +1595,7 @@ int hci_add_adv_entry(struct hci_dev *hdev,
if (hci_find_adv_entry(hdev, &ev->bdaddr))
return 0;
entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return -ENOMEM;
......@@ -1442,16 +1610,116 @@ int hci_add_adv_entry(struct hci_dev *hdev,
return 0;
}
static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
{
struct le_scan_params *param = (struct le_scan_params *) opt;
struct hci_cp_le_set_scan_param cp;
memset(&cp, 0, sizeof(cp));
cp.type = param->type;
cp.interval = cpu_to_le16(param->interval);
cp.window = cpu_to_le16(param->window);
hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
}
static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
{
struct hci_cp_le_set_scan_enable cp;
memset(&cp, 0, sizeof(cp));
cp.enable = 1;
hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}
static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
u16 window, int timeout)
{
long timeo = msecs_to_jiffies(3000);
struct le_scan_params param;
int err;
BT_DBG("%s", hdev->name);
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
return -EINPROGRESS;
param.type = type;
param.interval = interval;
param.window = window;
hci_req_lock(hdev);
err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
timeo);
if (!err)
err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
hci_req_unlock(hdev);
if (err < 0)
return err;
schedule_delayed_work(&hdev->le_scan_disable,
msecs_to_jiffies(timeout));
return 0;
}
static void le_scan_disable_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
le_scan_disable.work);
struct hci_cp_le_set_scan_enable cp;
BT_DBG("%s", hdev->name);
memset(&cp, 0, sizeof(cp));
hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
}
static void le_scan_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
struct le_scan_params *param = &hdev->le_scan_params;
BT_DBG("%s", hdev->name);
hci_do_le_scan(hdev, param->type, param->interval, param->window,
param->timeout);
}
int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
int timeout)
{
struct le_scan_params *param = &hdev->le_scan_params;
BT_DBG("%s", hdev->name);
if (work_busy(&hdev->le_scan))
return -EINPROGRESS;
param->type = type;
param->interval = interval;
param->window = window;
param->timeout = timeout;
queue_work(system_long_wq, &hdev->le_scan);
return 0;
}
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
{
struct list_head *head = &hci_dev_list, *p;
int i, id, error;
BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
hdev->bus, hdev->owner);
BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
if (!hdev->open || !hdev->close || !hdev->destruct)
if (!hdev->open || !hdev->close)
return -EINVAL;
/* Do not allow HCI_AMP devices to register at index 0,
......@@ -1472,7 +1740,6 @@ int hci_register_dev(struct hci_dev *hdev)
hdev->id = id;
list_add_tail(&hdev->list, head);
atomic_set(&hdev->refcnt, 1);
mutex_init(&hdev->lock);
hdev->flags = 0;
......@@ -1503,7 +1770,7 @@ int hci_register_dev(struct hci_dev *hdev)
init_waitqueue_head(&hdev->req_wait_q);
mutex_init(&hdev->req_lock);
inquiry_cache_init(hdev);
discovery_init(hdev);
hci_conn_hash_init(hdev);
......@@ -1514,6 +1781,7 @@ int hci_register_dev(struct hci_dev *hdev)
INIT_LIST_HEAD(&hdev->uuids);
INIT_LIST_HEAD(&hdev->link_keys);
INIT_LIST_HEAD(&hdev->long_term_keys);
INIT_LIST_HEAD(&hdev->remote_oob_data);
......@@ -1529,6 +1797,10 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set(&hdev->promisc, 0);
INIT_WORK(&hdev->le_scan, le_scan_work);
INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
write_unlock(&hci_dev_list_lock);
hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
......@@ -1551,11 +1823,12 @@ int hci_register_dev(struct hci_dev *hdev)
}
}
set_bit(HCI_AUTO_OFF, &hdev->flags);
set_bit(HCI_SETUP, &hdev->flags);
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
set_bit(HCI_SETUP, &hdev->dev_flags);
schedule_work(&hdev->power_on);
hci_notify(hdev, HCI_DEV_REG);
hci_dev_hold(hdev);
return id;
......@@ -1587,7 +1860,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
kfree_skb(hdev->reassembly[i]);
if (!test_bit(HCI_INIT, &hdev->flags) &&
!test_bit(HCI_SETUP, &hdev->flags)) {
!test_bit(HCI_SETUP, &hdev->dev_flags)) {
hci_dev_lock(hdev);
mgmt_index_removed(hdev);
hci_dev_unlock(hdev);
......@@ -1614,11 +1887,12 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_blacklist_clear(hdev);
hci_uuids_clear(hdev);
hci_link_keys_clear(hdev);
hci_smp_ltks_clear(hdev);
hci_remote_oob_data_clear(hdev);
hci_adv_entries_clear(hdev);
hci_dev_unlock(hdev);
__hci_dev_put(hdev);
hci_dev_put(hdev);
}
EXPORT_SYMBOL(hci_unregister_dev);
......@@ -1706,7 +1980,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
while (count) {
scb = (void *) skb->cb;
len = min(scb->expect, (__u16)count);
len = min_t(uint, scb->expect, count);
memcpy(skb_put(skb, len), data, len);
......@@ -1862,11 +2136,15 @@ static int hci_send_frame(struct sk_buff *skb)
BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
if (atomic_read(&hdev->promisc)) {
/* Time stamp */
__net_timestamp(skb);
/* Time stamp */
__net_timestamp(skb);
/* Send copy to monitor */
hci_send_to_monitor(hdev, skb);
hci_send_to_sock(hdev, skb, NULL);
if (atomic_read(&hdev->promisc)) {
/* Send copy to the sockets */
hci_send_to_sock(hdev, skb);
}
/* Get rid of skb owner, prior to sending to the driver. */
......@@ -2235,26 +2513,31 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
}
static inline void hci_sched_acl(struct hci_dev *hdev)
static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_chan *chan;
struct sk_buff *skb;
int quote;
unsigned int cnt;
BT_DBG("%s", hdev->name);
if (!hci_conn_num(hdev, ACL_LINK))
return;
/* Calculate count of blocks used by this packet */
return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
}
static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
{
if (!test_bit(HCI_RAW, &hdev->flags)) {
/* ACL tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
if (!cnt && time_after(jiffies, hdev->acl_last_tx +
msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
hci_link_tx_to(hdev, ACL_LINK);
}
}
static inline void hci_sched_acl_pkt(struct hci_dev *hdev)
{
unsigned int cnt = hdev->acl_cnt;
struct hci_chan *chan;
struct sk_buff *skb;
int quote;
cnt = hdev->acl_cnt;
__check_timeout(hdev, cnt);
while (hdev->acl_cnt &&
(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
......@@ -2270,7 +2553,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
skb = skb_dequeue(&chan->data_q);
hci_conn_enter_active_mode(chan->conn,
bt_cb(skb)->force_active);
bt_cb(skb)->force_active);
hci_send_frame(skb);
hdev->acl_last_tx = jiffies;
......@@ -2285,6 +2568,70 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
hci_prio_recalculate(hdev, ACL_LINK);
}
static inline void hci_sched_acl_blk(struct hci_dev *hdev)
{
unsigned int cnt = hdev->block_cnt;
struct hci_chan *chan;
struct sk_buff *skb;
int quote;
__check_timeout(hdev, cnt);
while (hdev->block_cnt > 0 &&
(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
u32 priority = (skb_peek(&chan->data_q))->priority;
while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
int blocks;
BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
skb->len, skb->priority);
/* Stop if priority has changed */
if (skb->priority < priority)
break;
skb = skb_dequeue(&chan->data_q);
blocks = __get_blocks(hdev, skb);
if (blocks > hdev->block_cnt)
return;
hci_conn_enter_active_mode(chan->conn,
bt_cb(skb)->force_active);
hci_send_frame(skb);
hdev->acl_last_tx = jiffies;
hdev->block_cnt -= blocks;
quote -= blocks;
chan->sent += blocks;
chan->conn->sent += blocks;
}
}
if (cnt != hdev->block_cnt)
hci_prio_recalculate(hdev, ACL_LINK);
}
static inline void hci_sched_acl(struct hci_dev *hdev)
{
BT_DBG("%s", hdev->name);
if (!hci_conn_num(hdev, ACL_LINK))
return;
switch (hdev->flow_ctl_mode) {
case HCI_FLOW_CTL_MODE_PACKET_BASED:
hci_sched_acl_pkt(hdev);
break;
case HCI_FLOW_CTL_MODE_BLOCK_BASED:
hci_sched_acl_blk(hdev);
break;
}
}
/* Schedule SCO */
static inline void hci_sched_sco(struct hci_dev *hdev)
{
......@@ -2482,9 +2829,12 @@ static void hci_rx_work(struct work_struct *work)
BT_DBG("%s", hdev->name);
while ((skb = skb_dequeue(&hdev->rx_q))) {
/* Send copy to monitor */
hci_send_to_monitor(hdev, skb);
if (atomic_read(&hdev->promisc)) {
/* Send copy to the sockets */
hci_send_to_sock(hdev, skb, NULL);
hci_send_to_sock(hdev, skb);
}
if (test_bit(HCI_RAW, &hdev->flags)) {
......@@ -2568,6 +2918,8 @@ int hci_do_inquiry(struct hci_dev *hdev, u8 length)
if (test_bit(HCI_INQUIRY, &hdev->flags))
return -EINPROGRESS;
inquiry_cache_flush(hdev);
memset(&cp, 0, sizeof(cp));
memcpy(&cp.lap, lap, sizeof(cp.lap));
cp.length = length;
......@@ -2584,6 +2936,3 @@ int hci_cancel_inquiry(struct hci_dev *hdev)
return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
}
module_param(enable_hs, bool, 0644);
MODULE_PARM_DESC(enable_hs, "Enable High Speed");
......@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <net/sock.h>
#include <asm/system.h>
......@@ -45,8 +44,6 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
static bool enable_le;
/* Handle HCI Event packets */
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -65,7 +62,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
mgmt_discovering(hdev, 0);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hci_dev_unlock(hdev);
hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
......@@ -195,7 +192,10 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
hci_req_complete(hdev, HCI_OP_RESET, status);
hdev->dev_flags = 0;
/* Reset all non-persistent flags */
hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS));
hdev->discovery.state = DISCOVERY_STOPPED;
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -211,13 +211,14 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_set_local_name_complete(hdev, sent, status);
if (status == 0)
else if (!status)
memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
hci_dev_unlock(hdev);
hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
}
static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -229,7 +230,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
if (rp->status)
return;
memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
if (test_bit(HCI_SETUP, &hdev->dev_flags))
memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
}
static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -252,6 +254,9 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_AUTH, &hdev->flags);
}
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_auth_enable_complete(hdev, status);
hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
}
......@@ -349,14 +354,19 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
if (!sent)
return;
memcpy(hdev->dev_class, sent, 3);
hci_dev_lock(hdev);
if (status == 0)
memcpy(hdev->dev_class, sent, 3);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_set_class_of_dev_complete(hdev, sent, status);
hci_dev_unlock(hdev);
}
static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -419,18 +429,6 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
}
static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
if (rp->status)
return;
hdev->ssp_mode = rp->mode;
}
static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
......@@ -438,14 +436,18 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
if (status)
return;
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
if (!sent)
return;
hdev->ssp_mode = *((__u8 *) sent);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
else if (!status) {
if (*((u8 *) sent))
set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
else
clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
}
}
static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
......@@ -540,20 +542,6 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
}
static void hci_set_le_support(struct hci_dev *hdev)
{
struct hci_cp_write_le_host_supported cp;
memset(&cp, 0, sizeof(cp));
if (enable_le) {
cp.le = 1;
cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
}
hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
}
static void hci_setup(struct hci_dev *hdev)
{
if (hdev->dev_type != HCI_BREDR)
......@@ -565,8 +553,18 @@ static void hci_setup(struct hci_dev *hdev)
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
if (hdev->features[6] & LMP_SIMPLE_PAIR) {
u8 mode = 0x01;
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
u8 mode = 0x01;
hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
sizeof(mode), &mode);
} else {
struct hci_cp_write_eir cp;
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(&cp, 0, sizeof(cp));
hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
}
}
if (hdev->features[3] & LMP_RSSI_INQ)
......@@ -579,12 +577,15 @@ static void hci_setup(struct hci_dev *hdev)
struct hci_cp_read_local_ext_features cp;
cp.page = 0x01;
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
sizeof(cp), &cp);
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
&cp);
}
if (hdev->features[4] & LMP_LE)
hci_set_le_support(hdev);
if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
u8 enable = 1;
hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
&enable);
}
}
static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -594,7 +595,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, rp->status);
if (rp->status)
return;
goto done;
hdev->hci_ver = rp->hci_ver;
hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
......@@ -608,6 +609,9 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
if (test_bit(HCI_INIT, &hdev->flags))
hci_setup(hdev);
done:
hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
}
static void hci_setup_link_policy(struct hci_dev *hdev)
......@@ -624,8 +628,8 @@ static void hci_setup_link_policy(struct hci_dev *hdev)
link_policy |= HCI_LP_PARK;
link_policy = cpu_to_le16(link_policy);
hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
sizeof(link_policy), &link_policy);
hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(link_policy),
&link_policy);
}
static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
......@@ -701,6 +705,22 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb
hdev->features[6], hdev->features[7]);
}
static void hci_set_le_support(struct hci_dev *hdev)
{
struct hci_cp_write_le_host_supported cp;
memset(&cp, 0, sizeof(cp));
if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
cp.le = 1;
cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
}
if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
&cp);
}
static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
struct sk_buff *skb)
{
......@@ -709,7 +729,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
BT_DBG("%s status 0x%x", hdev->name, rp->status);
if (rp->status)
return;
goto done;
switch (rp->page) {
case 0:
......@@ -720,6 +740,10 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
break;
}
if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE)
hci_set_le_support(hdev);
done:
hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
}
......@@ -890,7 +914,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
if (rp->status != 0)
......@@ -916,7 +940,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
rp->status);
......@@ -951,9 +975,9 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
rp->status);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
rp->status);
hci_dev_unlock(hdev);
}
......@@ -967,9 +991,9 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
rp->status);
ACL_LINK, 0, rp->status);
hci_dev_unlock(hdev);
}
......@@ -982,9 +1006,9 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr,
rp->status);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
0, rp->status);
hci_dev_unlock(hdev);
}
......@@ -998,9 +1022,9 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
rp->status);
ACL_LINK, 0, rp->status);
hci_dev_unlock(hdev);
}
......@@ -1023,6 +1047,15 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
if (status) {
hci_dev_lock(hdev);
mgmt_start_discovery_failed(hdev, status);
hci_dev_unlock(hdev);
return;
}
}
static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
......@@ -1033,28 +1066,47 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
BT_DBG("%s status 0x%x", hdev->name, status);
if (status)
return;
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
if (!cp)
return;
switch (cp->enable) {
case LE_SCANNING_ENABLED:
hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
if (status) {
hci_dev_lock(hdev);
mgmt_start_discovery_failed(hdev, status);
hci_dev_unlock(hdev);
return;
}
set_bit(HCI_LE_SCAN, &hdev->dev_flags);
cancel_delayed_work_sync(&hdev->adv_work);
hci_dev_lock(hdev);
hci_adv_entries_clear(hdev);
hci_discovery_set_state(hdev, DISCOVERY_FINDING);
hci_dev_unlock(hdev);
break;
case LE_SCANNING_DISABLED:
if (status)
return;
clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
mgmt_interleaved_discovery(hdev);
} else {
hci_dev_lock(hdev);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hci_dev_unlock(hdev);
}
break;
default:
......@@ -1090,16 +1142,27 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_cp_read_local_ext_features cp;
struct hci_cp_write_le_host_supported *sent;
__u8 status = *((__u8 *) skb->data);
BT_DBG("%s status 0x%x", hdev->name, status);
if (status)
sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
if (!sent)
return;
cp.page = 0x01;
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
if (!status) {
if (sent->le)
hdev->host_features[0] |= LMP_HOST_LE;
else
hdev->host_features[0] &= ~LMP_HOST_LE;
}
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
!test_bit(HCI_INIT, &hdev->flags))
mgmt_le_enable_complete(hdev, sent->le, status);
hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
}
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
......@@ -1110,7 +1173,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_start_discovery_failed(hdev, status);
hci_dev_unlock(hdev);
return;
......@@ -1119,7 +1182,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
set_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
mgmt_discovering(hdev, 1);
hci_discovery_set_state(hdev, DISCOVERY_FINDING);
hci_dev_unlock(hdev);
}
......@@ -1153,7 +1216,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
if (!conn) {
conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
if (conn) {
conn->out = 1;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
} else
BT_ERR("No memory for new connection");
......@@ -1263,7 +1326,7 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
/* Only request authentication for SSP connections or non-SSP
* devices with sec_level HIGH or if MITM protection is requested */
if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
if (!hci_conn_ssp_enabled(conn) &&
conn->pending_sec_level != BT_SECURITY_HIGH &&
!(conn->auth_type & 0x01))
return 0;
......@@ -1271,6 +1334,73 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
return 1;
}
static inline int hci_resolve_name(struct hci_dev *hdev,
struct inquiry_entry *e)
{
struct hci_cp_remote_name_req cp;
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, &e->data.bdaddr);
cp.pscan_rep_mode = e->data.pscan_rep_mode;
cp.pscan_mode = e->data.pscan_mode;
cp.clock_offset = e->data.clock_offset;
return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
}
static bool hci_resolve_next_name(struct hci_dev *hdev)
{
struct discovery_state *discov = &hdev->discovery;
struct inquiry_entry *e;
if (list_empty(&discov->resolve))
return false;
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
if (hci_resolve_name(hdev, e) == 0) {
e->name_state = NAME_PENDING;
return true;
}
return false;
}
static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
bdaddr_t *bdaddr, u8 *name, u8 name_len)
{
struct discovery_state *discov = &hdev->discovery;
struct inquiry_entry *e;
if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
name_len, conn->dev_class);
if (discov->state == DISCOVERY_STOPPED)
return;
if (discov->state == DISCOVERY_STOPPING)
goto discov_complete;
if (discov->state != DISCOVERY_RESOLVING)
return;
e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
if (e) {
e->name_state = NAME_KNOWN;
list_del(&e->list);
if (name)
mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
e->data.rssi, name, name_len);
}
if (hci_resolve_next_name(hdev))
return;
discov_complete:
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
}
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
{
struct hci_cp_remote_name_req *cp;
......@@ -1290,13 +1420,17 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
if (!conn)
goto unlock;
if (!hci_outgoing_auth_needed(hdev, conn))
goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
......@@ -1413,9 +1547,9 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn) {
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
hci_sco_setup(conn, status);
}
......@@ -1440,15 +1574,37 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn) {
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
hci_sco_setup(conn, status);
}
hci_dev_unlock(hdev);
}
static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
{
struct hci_cp_disconnect *cp;
struct hci_conn *conn;
if (!status)
return;
cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
if (!cp)
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
if (conn)
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status);
hci_dev_unlock(hdev);
}
static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
{
struct hci_cp_le_create_conn *cp;
......@@ -1478,7 +1634,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
if (conn) {
conn->dst_type = cp->peer_addr_type;
conn->out = 1;
conn->out = true;
} else {
BT_ERR("No memory for new connection");
}
......@@ -1496,6 +1652,8 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
struct discovery_state *discov = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("%s status %d", hdev->name, status);
......@@ -1506,8 +1664,28 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
return;
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
return;
hci_dev_lock(hdev);
mgmt_discovering(hdev, 0);
if (discov->state != DISCOVERY_FINDING)
goto unlock;
if (list_empty(&discov->resolve)) {
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
goto unlock;
}
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
if (e && hci_resolve_name(hdev, e) == 0) {
e->name_state = NAME_PENDING;
hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
} else {
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
}
unlock:
hci_dev_unlock(hdev);
}
......@@ -1525,6 +1703,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
bool name_known, ssp;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
......@@ -1533,9 +1713,11 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data.clock_offset = info->clock_offset;
data.rssi = 0x00;
data.ssp_mode = 0x00;
hci_inquiry_cache_update(hdev, &data);
name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, 0, NULL);
info->dev_class, 0, !name_known, ssp, NULL,
0);
}
hci_dev_unlock(hdev);
......@@ -1569,8 +1751,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn->state = BT_CONFIG;
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
mgmt_connected(hdev, &ev->bdaddr, conn->type,
conn->dst_type);
} else
conn->state = BT_CONNECTED;
......@@ -1588,7 +1768,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
struct hci_cp_read_remote_features cp;
cp.handle = ev->handle;
hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
sizeof(cp), &cp);
sizeof(cp), &cp);
}
/* Set packet type for incoming connection */
......@@ -1596,14 +1776,14 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
struct hci_cp_change_conn_ptype cp;
cp.handle = ev->handle;
cp.pkt_type = cpu_to_le16(conn->pkt_type);
hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
sizeof(cp), &cp);
hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
&cp);
}
} else {
conn->state = BT_CLOSED;
if (conn->type == ACL_LINK)
mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
conn->dst_type, ev->status);
conn->dst_type, ev->status);
}
if (conn->type == ACL_LINK)
......@@ -1668,8 +1848,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
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 {
struct hci_cp_accept_sync_conn_req cp;
......@@ -1683,7 +1863,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
cp.retrans_effort = 0xff;
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp);
sizeof(cp), &cp);
}
} else {
/* Connection rejected */
......@@ -1711,12 +1891,14 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
if (ev->status == 0)
conn->state = BT_CLOSED;
if (conn->type == ACL_LINK || conn->type == LE_LINK) {
if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
(conn->type == ACL_LINK || conn->type == LE_LINK)) {
if (ev->status != 0)
mgmt_disconnect_failed(hdev, &conn->dst, ev->status);
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, ev->status);
else
mgmt_disconnected(hdev, &conn->dst, conn->type,
conn->dst_type);
mgmt_device_disconnected(hdev, &conn->dst, conn->type,
conn->dst_type);
}
if (ev->status == 0) {
......@@ -1742,22 +1924,23 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
goto unlock;
if (!ev->status) {
if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
if (!hci_conn_ssp_enabled(conn) &&
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;
conn->sec_level = conn->pending_sec_level;
}
} else {
mgmt_auth_failed(hdev, &conn->dst, ev->status);
mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
ev->status);
}
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
if (conn->state == BT_CONFIG) {
if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
if (!ev->status && hci_conn_ssp_enabled(conn)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = ev->handle;
cp.encrypt = 0x01;
......@@ -1776,7 +1959,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
hci_conn_put(conn);
}
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
if (!ev->status) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = ev->handle;
......@@ -1784,7 +1967,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
&cp);
} else {
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
hci_encrypt_cfm(conn, ev->status, 0x00);
}
}
......@@ -1804,17 +1987,25 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
hci_dev_lock(hdev);
if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
goto check_auth;
if (ev->status == 0)
hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
strnlen(ev->name, HCI_MAX_NAME_LENGTH));
else
hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
check_auth:
if (!conn)
goto unlock;
if (!hci_outgoing_auth_needed(hdev, conn))
goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
......@@ -1845,7 +2036,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
conn->link_mode &= ~HCI_LM_ENCRYPT;
}
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (conn->state == BT_CONFIG) {
if (!ev->status)
......@@ -1874,7 +2065,7 @@ static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct
if (!ev->status)
conn->link_mode |= HCI_LM_SECURE;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
hci_key_change_cfm(conn, ev->status);
}
......@@ -1916,7 +2107,10 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
}
} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, &conn->dst, conn->type,
conn->dst_type, 0, NULL, 0,
conn->dev_class);
if (!hci_outgoing_auth_needed(hdev, conn)) {
conn->state = BT_CONNECTED;
......@@ -2024,10 +2218,6 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_host_buffer_size(hdev, skb);
break;
case HCI_OP_READ_SSP_MODE:
hci_cc_read_ssp_mode(hdev, skb);
break;
case HCI_OP_WRITE_SSP_MODE:
hci_cc_write_ssp_mode(hdev, skb);
break;
......@@ -2213,8 +2403,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
break;
case HCI_OP_DISCONNECT:
if (ev->status != 0)
mgmt_disconnect_failed(hdev, NULL, ev->status);
hci_cs_disconnect(hdev, ev->status);
break;
case HCI_OP_LE_CREATE_CONN:
......@@ -2258,7 +2447,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
conn->link_mode |= HCI_LM_MASTER;
}
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
hci_role_switch_cfm(conn, ev->status, ev->role);
}
......@@ -2332,6 +2521,56 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
queue_work(hdev->workqueue, &hdev->tx_work);
}
static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
int i;
if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
return;
}
if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
BT_DBG("%s bad parameters", hdev->name);
return;
}
BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
ev->num_hndl);
for (i = 0; i < ev->num_hndl; i++) {
struct hci_comp_blocks_info *info = &ev->handles[i];
struct hci_conn *conn;
__u16 handle, block_count;
handle = __le16_to_cpu(info->handle);
block_count = __le16_to_cpu(info->blocks);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (!conn)
continue;
conn->sent -= block_count;
switch (conn->type) {
case ACL_LINK:
hdev->block_cnt += block_count;
if (hdev->block_cnt > hdev->num_blocks)
hdev->block_cnt = hdev->num_blocks;
break;
default:
BT_ERR("Unknown type %d conn %p", conn->type, conn);
break;
}
}
queue_work(hdev->workqueue, &hdev->tx_work);
}
static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_mode_change *ev = (void *) skb->data;
......@@ -2346,14 +2585,14 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
conn->mode = ev->mode;
conn->interval = __le16_to_cpu(ev->interval);
if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
if (conn->mode == HCI_CM_ACTIVE)
conn->power_save = 1;
set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
else
conn->power_save = 0;
clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
}
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
hci_sco_setup(conn, ev->status);
}
......@@ -2379,10 +2618,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_put(conn);
}
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
else if (test_bit(HCI_MGMT, &hdev->flags)) {
else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
u8 secure;
if (conn->pending_sec_level == BT_SECURITY_HIGH)
......@@ -2406,7 +2645,7 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s", hdev->name);
if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
return;
hci_dev_lock(hdev);
......@@ -2421,7 +2660,7 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG("%s found key type %u for %s", hdev->name, key->type,
batostr(&ev->bdaddr));
if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
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;
......@@ -2483,7 +2722,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_put(conn);
}
if (test_bit(HCI_LINK_KEYS, &hdev->flags))
if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
......@@ -2551,6 +2790,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
{
struct inquiry_data data;
int num_rsp = *((__u8 *) skb->data);
bool name_known, ssp;
BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
......@@ -2572,10 +2812,12 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
hci_inquiry_cache_update(hdev, &data);
name_known = hci_inquiry_cache_update(hdev, &data,
false, &ssp);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
NULL);
info->dev_class, info->rssi,
!name_known, ssp, NULL, 0);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
......@@ -2589,10 +2831,11 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
hci_inquiry_cache_update(hdev, &data);
name_known = hci_inquiry_cache_update(hdev, &data,
false, &ssp);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
NULL);
info->dev_class, info->rssi,
!name_known, ssp, NULL, 0);
}
}
......@@ -2617,9 +2860,10 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
if (ie)
ie->data.ssp_mode = (ev->features[0] & 0x01);
ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
conn->ssp_mode = (ev->features[0] & 0x01);
if (ev->features[0] & LMP_HOST_SSP)
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
}
if (conn->state != BT_CONFIG)
......@@ -2631,7 +2875,10 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
bacpy(&cp.bdaddr, &conn->dst);
cp.pscan_rep_mode = 0x02;
hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
}
} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, &conn->dst, conn->type,
conn->dst_type, 0, NULL, 0,
conn->dev_class);
if (!hci_outgoing_auth_needed(hdev, conn)) {
conn->state = BT_CONNECTED;
......@@ -2724,6 +2971,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
bool name_known, ssp;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
......@@ -2732,9 +2981,19 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x01;
hci_inquiry_cache_update(hdev, &data);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
name_known = eir_has_data_type(info->data,
sizeof(info->data),
EIR_NAME_COMPLETE);
else
name_known = true;
name_known = hci_inquiry_cache_update(hdev, &data, name_known,
&ssp);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi, info->data);
info->dev_class, info->rssi, !name_known,
ssp, info->data, sizeof(info->data));
}
hci_dev_unlock(hdev);
......@@ -2774,19 +3033,22 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_hold(conn);
if (!test_bit(HCI_MGMT, &hdev->flags))
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
goto unlock;
if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
struct hci_cp_io_capability_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.capability = conn->io_capability;
/* Change the IO capability from KeyboardDisplay
* to DisplayYesNo as it is not supported by BT spec. */
cp.capability = (conn->io_capability == 0x04) ?
0x01 : conn->io_capability;
conn->auth_type = hci_get_auth_req(conn);
cp.authentication = conn->auth_type;
if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
hci_find_remote_oob_data(hdev, &conn->dst))
cp.oob_data = 0x01;
else
......@@ -2822,8 +3084,9 @@ static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *s
goto unlock;
conn->remote_cap = ev->capability;
conn->remote_oob = ev->oob_data;
conn->remote_auth = ev->authentication;
if (ev->oob_data)
set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
unlock:
hci_dev_unlock(hdev);
......@@ -2840,7 +3103,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
hci_dev_lock(hdev);
if (!test_bit(HCI_MGMT, &hdev->flags))
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
goto unlock;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
......@@ -2869,7 +3132,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
* confirm_hint set to 1). */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
BT_DBG("Confirming auto-accept as acceptor");
confirm_hint = 1;
goto confirm;
......@@ -2890,8 +3153,8 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
}
confirm:
mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
confirm_hint);
mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
confirm_hint);
unlock:
hci_dev_unlock(hdev);
......@@ -2906,8 +3169,8 @@ static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_passkey_request(hdev, &ev->bdaddr);
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
hci_dev_unlock(hdev);
}
......@@ -2930,8 +3193,9 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_
* initiated the authentication. A traditional auth_complete
* event gets always produced as initiator and is also mapped to
* the mgmt_auth_failed event */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
mgmt_auth_failed(hdev, &conn->dst, ev->status);
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
ev->status);
hci_conn_put(conn);
......@@ -2950,13 +3214,13 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
if (ie)
ie->data.ssp_mode = (ev->features[0] & 0x01);
ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
hci_dev_unlock(hdev);
}
static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
struct sk_buff *skb)
{
struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
struct oob_data *data;
......@@ -2965,7 +3229,7 @@ static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
hci_dev_lock(hdev);
if (!test_bit(HCI_MGMT, &hdev->flags))
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
goto unlock;
data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
......@@ -3020,7 +3284,9 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
goto unlock;
}
mgmt_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type);
if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
conn->dst_type, 0, NULL, 0, NULL);
conn->sec_level = BT_SECURITY_LOW;
conn->handle = __le16_to_cpu(ev->handle);
......@@ -3040,6 +3306,7 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
{
u8 num_reports = skb->data[0];
void *ptr = &skb->data[1];
s8 rssi;
hci_dev_lock(hdev);
......@@ -3048,6 +3315,10 @@ static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
hci_add_adv_entry(hdev, ev);
rssi = ev->data[ev->length];
mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
NULL, rssi, 0, 1, ev->data, ev->length);
ptr += sizeof(*ev) + ev->length + 1;
}
......@@ -3061,7 +3332,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
struct hci_cp_le_ltk_reply cp;
struct hci_cp_le_ltk_neg_reply neg;
struct hci_conn *conn;
struct link_key *ltk;
struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
......@@ -3077,10 +3348,17 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
cp.handle = cpu_to_le16(conn->handle);
conn->pin_length = ltk->pin_len;
if (ltk->authenticated)
conn->sec_level = BT_SECURITY_HIGH;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
if (ltk->type & HCI_SMP_STK) {
list_del(&ltk->list);
kfree(ltk);
}
hci_dev_unlock(hdev);
return;
......@@ -3271,6 +3549,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_remote_oob_data_request_evt(hdev, skb);
break;
case HCI_EV_NUM_COMP_BLOCKS:
hci_num_comp_blocks_evt(hdev, skb);
break;
default:
BT_DBG("%s event 0x%x", hdev->name, event);
break;
......@@ -3279,34 +3561,3 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
kfree_skb(skb);
hdev->stat.evt_rx++;
}
/* Generate internal stack event */
void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
{
struct hci_event_hdr *hdr;
struct hci_ev_stack_internal *ev;
struct sk_buff *skb;
skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
if (!skb)
return;
hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;
ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);
bt_cb(skb)->incoming = 1;
__net_timestamp(skb);
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb, NULL);
kfree_skb(skb);
}
module_param(enable_le, bool, 0644);
MODULE_PARM_DESC(enable_le, "Enable LE support");
......@@ -48,8 +48,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_mon.h>
static bool enable_mgmt;
static atomic_t monitor_promisc = ATOMIC_INIT(0);
/* ----- HCI socket interface ----- */
......@@ -85,22 +86,20 @@ static struct bt_sock_list hci_sk_list = {
};
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
struct sock *skip_sk)
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
struct sk_buff *skb_copy = NULL;
BT_DBG("hdev %p len %d", hdev, skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct hci_filter *flt;
struct sk_buff *nskb;
if (sk == skip_sk)
continue;
if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
continue;
......@@ -108,12 +107,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
if (skb->sk == sk)
continue;
if (bt_cb(skb)->channel != hci_pi(sk)->channel)
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
continue;
if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
goto clone;
/* Apply filter */
flt = &hci_pi(sk)->filter;
......@@ -137,21 +133,303 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
continue;
}
clone:
if (!skb_copy) {
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
if (!skb_copy)
continue;
/* Put type byte before the data */
memcpy(skb_push(skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
}
nskb = skb_clone(skb_copy, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
kfree_skb(skb_copy);
}
/* Send frame to control socket */
void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
{
struct sock *sk;
struct hlist_node *node;
BT_DBG("len %d", skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
/* Skip the original socket */
if (sk == skip_sk)
continue;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
continue;
nskb = skb_clone(skb, GFP_ATOMIC);
if (!nskb)
continue;
/* Put type byte before the data */
if (bt_cb(skb)->channel == HCI_CHANNEL_RAW)
memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
}
/* Send frame to monitor socket */
void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
struct sk_buff *skb_copy = NULL;
__le16 opcode;
if (!atomic_read(&monitor_promisc))
return;
BT_DBG("hdev %p len %d", hdev, skb->len);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT);
break;
case HCI_EVENT_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT);
break;
case HCI_ACLDATA_PKT:
if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT);
else
opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT);
break;
case HCI_SCODATA_PKT:
if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT);
else
opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT);
break;
default:
return;
}
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
continue;
if (!skb_copy) {
struct hci_mon_hdr *hdr;
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC);
if (!skb_copy)
continue;
/* Put header before the data */
hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len);
}
nskb = skb_clone(skb_copy, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
kfree_skb(skb_copy);
}
static void send_monitor_event(struct sk_buff *skb)
{
struct sock *sk;
struct hlist_node *node;
BT_DBG("len %d", skb->len);
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND)
continue;
if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
continue;
nskb = skb_clone(skb, GFP_ATOMIC);
if (!nskb)
continue;
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
}
static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
{
struct hci_mon_hdr *hdr;
struct hci_mon_new_index *ni;
struct sk_buff *skb;
__le16 opcode;
switch (event) {
case HCI_DEV_REG:
skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
if (!skb)
return NULL;
ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
ni->type = hdev->dev_type;
ni->bus = hdev->bus;
bacpy(&ni->bdaddr, &hdev->bdaddr);
memcpy(ni->name, hdev->name, 8);
opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX);
break;
case HCI_DEV_UNREG:
skb = bt_skb_alloc(0, GFP_ATOMIC);
if (!skb)
return NULL;
opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX);
break;
default:
return NULL;
}
__net_timestamp(skb);
hdr = (void *) skb_push(skb, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
return skb;
}
static void send_monitor_replay(struct sock *sk)
{
struct hci_dev *hdev;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list) {
struct sk_buff *skb;
skb = create_monitor_event(hdev, HCI_DEV_REG);
if (!skb)
continue;
if (sock_queue_rcv_skb(sk, skb))
kfree_skb(skb);
}
read_unlock(&hci_dev_list_lock);
}
/* Generate internal stack event */
static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
{
struct hci_event_hdr *hdr;
struct hci_ev_stack_internal *ev;
struct sk_buff *skb;
skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
if (!skb)
return;
hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;
ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);
bt_cb(skb)->incoming = 1;
__net_timestamp(skb);
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}
void hci_sock_dev_event(struct hci_dev *hdev, int event)
{
struct hci_ev_si_device ev;
BT_DBG("hdev %s event %d", hdev->name, event);
/* Send event to monitor */
if (atomic_read(&monitor_promisc)) {
struct sk_buff *skb;
skb = create_monitor_event(hdev, event);
if (skb) {
send_monitor_event(skb);
kfree_skb(skb);
}
}
/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);
hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
}
static int hci_sock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
......@@ -164,6 +442,9 @@ static int hci_sock_release(struct socket *sock)
hdev = hci_pi(sk)->hdev;
if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
atomic_dec(&monitor_promisc);
bt_sock_unlink(&hci_sk_list, sk);
if (hdev) {
......@@ -190,7 +471,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_add(hdev, &bdaddr);
err = hci_blacklist_add(hdev, &bdaddr, 0);
hci_dev_unlock(hdev);
......@@ -207,7 +488,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
hci_dev_lock(hdev);
err = hci_blacklist_del(hdev, &bdaddr);
err = hci_blacklist_del(hdev, &bdaddr, 0);
hci_dev_unlock(hdev);
......@@ -340,34 +621,69 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
if (haddr.hci_family != AF_BLUETOOTH)
return -EINVAL;
if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
return -EINVAL;
if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
if (!enable_mgmt)
return -EINVAL;
set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
}
lock_sock(sk);
if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) {
if (sk->sk_state == BT_BOUND) {
err = -EALREADY;
goto done;
}
if (haddr.hci_dev != HCI_DEV_NONE) {
hdev = hci_dev_get(haddr.hci_dev);
if (!hdev) {
err = -ENODEV;
switch (haddr.hci_channel) {
case HCI_CHANNEL_RAW:
if (hci_pi(sk)->hdev) {
err = -EALREADY;
goto done;
}
atomic_inc(&hdev->promisc);
if (haddr.hci_dev != HCI_DEV_NONE) {
hdev = hci_dev_get(haddr.hci_dev);
if (!hdev) {
err = -ENODEV;
goto done;
}
atomic_inc(&hdev->promisc);
}
hci_pi(sk)->hdev = hdev;
break;
case HCI_CHANNEL_CONTROL:
if (haddr.hci_dev != HCI_DEV_NONE) {
err = -EINVAL;
goto done;
}
if (!capable(CAP_NET_ADMIN)) {
err = -EPERM;
goto done;
}
break;
case HCI_CHANNEL_MONITOR:
if (haddr.hci_dev != HCI_DEV_NONE) {
err = -EINVAL;
goto done;
}
if (!capable(CAP_NET_RAW)) {
err = -EPERM;
goto done;
}
send_monitor_replay(sk);
atomic_inc(&monitor_promisc);
break;
default:
err = -EINVAL;
goto done;
}
hci_pi(sk)->channel = haddr.hci_channel;
hci_pi(sk)->hdev = hdev;
sk->sk_state = BT_BOUND;
done:
......@@ -461,7 +777,15 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
hci_sock_cmsg(sk, msg, skb);
switch (hci_pi(sk)->channel) {
case HCI_CHANNEL_RAW:
hci_sock_cmsg(sk, msg, skb);
break;
case HCI_CHANNEL_CONTROL:
case HCI_CHANNEL_MONITOR:
sock_recv_timestamp(msg, sk, skb);
break;
}
skb_free_datagram(sk, skb);
......@@ -495,6 +819,9 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
case HCI_CHANNEL_CONTROL:
err = mgmt_control(sk, msg, len);
goto done;
case HCI_CHANNEL_MONITOR:
err = -EOPNOTSUPP;
goto done;
default:
err = -EINVAL;
goto done;
......@@ -574,6 +901,11 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
lock_sock(sk);
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
err = -EINVAL;
goto done;
}
switch (optname) {
case HCI_DATA_DIR:
if (get_user(opt, (int __user *)optval)) {
......@@ -636,6 +968,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
break;
}
done:
release_sock(sk);
return err;
}
......@@ -644,11 +977,20 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
{
struct hci_ufilter uf;
struct sock *sk = sock->sk;
int len, opt;
int len, opt, err = 0;
BT_DBG("sk %p, opt %d", sk, optname);
if (get_user(len, optlen))
return -EFAULT;
lock_sock(sk);
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
err = -EINVAL;
goto done;
}
switch (optname) {
case HCI_DATA_DIR:
if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
......@@ -657,7 +999,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
opt = 0;
if (put_user(opt, optval))
return -EFAULT;
err = -EFAULT;
break;
case HCI_TIME_STAMP:
......@@ -667,7 +1009,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
opt = 0;
if (put_user(opt, optval))
return -EFAULT;
err = -EFAULT;
break;
case HCI_FILTER:
......@@ -682,15 +1024,17 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char
len = min_t(unsigned int, len, sizeof(uf));
if (copy_to_user(optval, &uf, len))
return -EFAULT;
err = -EFAULT;
break;
default:
return -ENOPROTOOPT;
err = -ENOPROTOOPT;
break;
}
return 0;
done:
release_sock(sk);
return err;
}
static const struct proto_ops hci_sock_ops = {
......@@ -748,52 +1092,12 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
return 0;
}
static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct hci_dev *hdev = (struct hci_dev *) ptr;
struct hci_ev_si_device ev;
BT_DBG("hdev %s event %ld", hdev->name, event);
/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;
/* Detach sockets from device */
read_lock(&hci_sk_list.lock);
sk_for_each(sk, node, &hci_sk_list.head) {
bh_lock_sock_nested(sk);
if (hci_pi(sk)->hdev == hdev) {
hci_pi(sk)->hdev = NULL;
sk->sk_err = EPIPE;
sk->sk_state = BT_OPEN;
sk->sk_state_change(sk);
hci_dev_put(hdev);
}
bh_unlock_sock(sk);
}
read_unlock(&hci_sk_list.lock);
}
return NOTIFY_DONE;
}
static const struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
};
static struct notifier_block hci_sock_nblock = {
.notifier_call = hci_sock_dev_event
};
int __init hci_sock_init(void)
{
int err;
......@@ -806,8 +1110,6 @@ int __init hci_sock_init(void)
if (err < 0)
goto error;
hci_register_notifier(&hci_sock_nblock);
BT_INFO("HCI socket layer initialized");
return 0;
......@@ -823,10 +1125,5 @@ void hci_sock_cleanup(void)
if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed");
hci_unregister_notifier(&hci_sock_nblock);
proto_unregister(&hci_sk_proto);
}
module_param(enable_mgmt, bool, 0644);
MODULE_PARM_DESC(enable_mgmt, "Enable Management interface");
......@@ -33,19 +33,19 @@ static inline char *link_typetostr(int type)
static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "%s\n", link_typetostr(conn->type));
}
static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "%s\n", batostr(&conn->dst));
}
static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_conn *conn = dev_get_drvdata(dev);
struct hci_conn *conn = to_hci_conn(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
conn->features[0], conn->features[1],
......@@ -79,8 +79,8 @@ static const struct attribute_group *bt_link_groups[] = {
static void bt_link_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
struct hci_conn *conn = to_hci_conn(dev);
kfree(conn);
}
static struct device_type bt_link = {
......@@ -120,8 +120,6 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
dev_set_drvdata(&conn->dev, conn);
if (device_add(&conn->dev) < 0) {
BT_ERR("Failed to register connection device");
return;
......@@ -189,19 +187,19 @@ static inline char *host_typetostr(int type)
static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", host_bustostr(hdev->bus));
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type));
}
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
char name[HCI_MAX_NAME_LENGTH + 1];
int i;
......@@ -214,20 +212,20 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr, char
static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "0x%.2x%.2x%.2x\n",
hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
}
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%s\n", batostr(&hdev->bdaddr));
}
static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
hdev->features[0], hdev->features[1],
......@@ -238,31 +236,31 @@ static ssize_t show_features(struct device *dev, struct device_attribute *attr,
static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->manufacturer);
}
static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->hci_ver);
}
static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->hci_rev);
}
static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->idle_timeout);
}
static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
unsigned int val;
int rv;
......@@ -280,13 +278,13 @@ static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *a
static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->sniff_max_interval);
}
static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
u16 val;
int rv;
......@@ -304,13 +302,13 @@ static ssize_t store_sniff_max_interval(struct device *dev, struct device_attrib
static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
return sprintf(buf, "%d\n", hdev->sniff_min_interval);
}
static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
struct hci_dev *hdev = to_hci_dev(dev);
u16 val;
int rv;
......@@ -370,8 +368,9 @@ static const struct attribute_group *bt_host_groups[] = {
static void bt_host_release(struct device *dev)
{
void *data = dev_get_drvdata(dev);
kfree(data);
struct hci_dev *hdev = to_hci_dev(dev);
kfree(hdev);
module_put(THIS_MODULE);
}
static struct device_type bt_host = {
......@@ -383,12 +382,12 @@ static struct device_type bt_host = {
static int inquiry_cache_show(struct seq_file *f, void *p)
{
struct hci_dev *hdev = f->private;
struct inquiry_cache *cache = &hdev->inq_cache;
struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
hci_dev_lock(hdev);
for (e = cache->list; e; e = e->next) {
list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
batostr(&data->bdaddr),
......@@ -523,7 +522,7 @@ void hci_init_sysfs(struct hci_dev *hdev)
dev->type = &bt_host;
dev->class = bt_class;
dev_set_drvdata(dev, hdev);
__module_get(THIS_MODULE);
device_initialize(dev);
}
......
......@@ -160,10 +160,10 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
{
if (cmd == HIDPGETCONNLIST) {
struct hidp_connlist_req cl;
uint32_t uci;
u32 uci;
int err;
if (get_user(cl.cnum, (uint32_t __user *) arg) ||
if (get_user(cl.cnum, (u32 __user *) arg) ||
get_user(uci, (u32 __user *) (arg + 4)))
return -EFAULT;
......@@ -174,7 +174,7 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
err = hidp_get_connlist(&cl);
if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
if (!err && put_user(cl.cnum, (u32 __user *) arg))
err = -EFAULT;
return err;
......
......@@ -73,42 +73,28 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
static void l2cap_send_disconn_req(struct l2cap_conn *conn,
struct l2cap_chan *chan, int err);
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
/* ---- L2CAP channels ---- */
static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c, *r = NULL;
rcu_read_lock();
struct l2cap_chan *c;
list_for_each_entry_rcu(c, &conn->chan_l, list) {
if (c->dcid == cid) {
r = c;
break;
}
list_for_each_entry(c, &conn->chan_l, list) {
if (c->dcid == cid)
return c;
}
rcu_read_unlock();
return r;
return NULL;
}
static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
{
struct l2cap_chan *c, *r = NULL;
rcu_read_lock();
struct l2cap_chan *c;
list_for_each_entry_rcu(c, &conn->chan_l, list) {
if (c->scid == cid) {
r = c;
break;
}
list_for_each_entry(c, &conn->chan_l, list) {
if (c->scid == cid)
return c;
}
rcu_read_unlock();
return r;
return NULL;
}
/* Find channel with given SCID.
......@@ -117,36 +103,32 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 ci
{
struct l2cap_chan *c;
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_scid(conn, cid);
if (c)
lock_sock(c->sk);
mutex_unlock(&conn->chan_lock);
return c;
}
static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
{
struct l2cap_chan *c, *r = NULL;
rcu_read_lock();
struct l2cap_chan *c;
list_for_each_entry_rcu(c, &conn->chan_l, list) {
if (c->ident == ident) {
r = c;
break;
}
list_for_each_entry(c, &conn->chan_l, list) {
if (c->ident == ident)
return c;
}
rcu_read_unlock();
return r;
return NULL;
}
static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
{
struct l2cap_chan *c;
mutex_lock(&conn->chan_lock);
c = __l2cap_get_chan_by_ident(conn, ident);
if (c)
lock_sock(c->sk);
mutex_unlock(&conn->chan_lock);
return c;
}
......@@ -217,51 +199,51 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return 0;
}
static char *state_to_string(int state)
static void __l2cap_state_change(struct l2cap_chan *chan, int state)
{
switch(state) {
case BT_CONNECTED:
return "BT_CONNECTED";
case BT_OPEN:
return "BT_OPEN";
case BT_BOUND:
return "BT_BOUND";
case BT_LISTEN:
return "BT_LISTEN";
case BT_CONNECT:
return "BT_CONNECT";
case BT_CONNECT2:
return "BT_CONNECT2";
case BT_CONFIG:
return "BT_CONFIG";
case BT_DISCONN:
return "BT_DISCONN";
case BT_CLOSED:
return "BT_CLOSED";
}
BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
state_to_string(state));
return "invalid state";
chan->state = state;
chan->ops->state_change(chan->data, state);
}
static void l2cap_state_change(struct l2cap_chan *chan, int state)
{
BT_DBG("%p %s -> %s", chan, state_to_string(chan->state),
state_to_string(state));
struct sock *sk = chan->sk;
chan->state = state;
chan->ops->state_change(chan->data, state);
lock_sock(sk);
__l2cap_state_change(chan, state);
release_sock(sk);
}
static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
sk->sk_err = err;
}
static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
lock_sock(sk);
__l2cap_chan_set_err(chan, err);
release_sock(sk);
}
static void l2cap_chan_timeout(struct work_struct *work)
{
struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
chan_timer.work);
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
int reason;
BT_DBG("chan %p state %d", chan, chan->state);
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
lock_sock(sk);
mutex_lock(&conn->chan_lock);
l2cap_chan_lock(chan);
if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
reason = ECONNREFUSED;
......@@ -273,9 +255,11 @@ static void l2cap_chan_timeout(struct work_struct *work)
l2cap_chan_close(chan, reason);
release_sock(sk);
l2cap_chan_unlock(chan);
chan->ops->close(chan->data);
mutex_unlock(&conn->chan_lock);
l2cap_chan_put(chan);
}
......@@ -287,6 +271,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
if (!chan)
return NULL;
mutex_init(&chan->lock);
chan->sk = sk;
write_lock(&chan_list_lock);
......@@ -313,7 +299,7 @@ void l2cap_chan_destroy(struct l2cap_chan *chan)
l2cap_chan_put(chan);
}
static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
chan->psm, chan->dcid);
......@@ -322,7 +308,8 @@ static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->conn = conn;
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
switch (chan->chan_type) {
case L2CAP_CHAN_CONN_ORIENTED:
if (conn->hcon->type == LE_LINK) {
/* LE connection */
chan->omtu = L2CAP_LE_DEFAULT_MTU;
......@@ -333,12 +320,16 @@ static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
chan->scid = l2cap_alloc_cid(conn);
chan->omtu = L2CAP_DEFAULT_MTU;
}
} else if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
break;
case L2CAP_CHAN_CONN_LESS:
/* Connectionless socket */
chan->scid = L2CAP_CID_CONN_LESS;
chan->dcid = L2CAP_CID_CONN_LESS;
chan->omtu = L2CAP_DEFAULT_MTU;
} else {
break;
default:
/* Raw socket can send/recv signalling messages only */
chan->scid = L2CAP_CID_SIGNALING;
chan->dcid = L2CAP_CID_SIGNALING;
......@@ -354,11 +345,16 @@ static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
l2cap_chan_hold(chan);
list_add_rcu(&chan->list, &conn->chan_l);
list_add(&chan->list, &conn->chan_l);
}
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{
mutex_lock(&conn->chan_lock);
__l2cap_chan_add(conn, chan);
mutex_unlock(&conn->chan_lock);
}
/* Delete channel.
* Must be called on the locked socket. */
static void l2cap_chan_del(struct l2cap_chan *chan, int err)
{
struct sock *sk = chan->sk;
......@@ -371,8 +367,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
if (conn) {
/* Delete from channel list */
list_del_rcu(&chan->list);
synchronize_rcu();
list_del(&chan->list);
l2cap_chan_put(chan);
......@@ -380,11 +375,13 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
hci_conn_put(conn->hcon);
}
l2cap_state_change(chan, BT_CLOSED);
lock_sock(sk);
__l2cap_state_change(chan, BT_CLOSED);
sock_set_flag(sk, SOCK_ZAPPED);
if (err)
sk->sk_err = err;
__l2cap_chan_set_err(chan, err);
if (parent) {
bt_accept_unlink(sk);
......@@ -392,6 +389,8 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
} else
sk->sk_state_change(sk);
release_sock(sk);
if (!(test_bit(CONF_OUTPUT_DONE, &chan->conf_state) &&
test_bit(CONF_INPUT_DONE, &chan->conf_state)))
return;
......@@ -423,10 +422,12 @@ static void l2cap_chan_cleanup_listen(struct sock *parent)
/* Close not yet accepted channels */
while ((sk = bt_accept_dequeue(parent, NULL))) {
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
l2cap_chan_lock(chan);
__clear_chan_timer(chan);
lock_sock(sk);
l2cap_chan_close(chan, ECONNRESET);
release_sock(sk);
l2cap_chan_unlock(chan);
chan->ops->close(chan->data);
}
}
......@@ -436,14 +437,17 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
struct l2cap_conn *conn = chan->conn;
struct sock *sk = chan->sk;
BT_DBG("chan %p state %d socket %p", chan, chan->state, sk->sk_socket);
BT_DBG("chan %p state %s sk %p", chan,
state_to_string(chan->state), sk);
switch (chan->state) {
case BT_LISTEN:
lock_sock(sk);
l2cap_chan_cleanup_listen(sk);
l2cap_state_change(chan, BT_CLOSED);
__l2cap_state_change(chan, BT_CLOSED);
sock_set_flag(sk, SOCK_ZAPPED);
release_sock(sk);
break;
case BT_CONNECTED:
......@@ -486,7 +490,9 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
break;
default:
lock_sock(sk);
sock_set_flag(sk, SOCK_ZAPPED);
release_sock(sk);
break;
}
}
......@@ -661,6 +667,21 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
}
static void l2cap_send_conn_req(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = chan->conn;
struct l2cap_conn_req req;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
set_bit(CONF_CONNECT_PEND, &chan->conf_state);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
}
static void l2cap_do_start(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = chan->conn;
......@@ -670,17 +691,8 @@ static void l2cap_do_start(struct l2cap_chan *chan)
return;
if (l2cap_chan_check_security(chan) &&
__l2cap_no_conn_pending(chan)) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
set_bit(CONF_CONNECT_PEND, &chan->conf_state);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
sizeof(req), &req);
}
__l2cap_no_conn_pending(chan))
l2cap_send_conn_req(chan);
} else {
struct l2cap_info_req req;
req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
......@@ -688,8 +700,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
conn->info_ident = l2cap_get_ident(conn);
schedule_delayed_work(&conn->info_timer,
msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
l2cap_send_cmd(conn, conn->info_ident,
L2CAP_INFO_REQ, sizeof(req), &req);
......@@ -714,14 +725,12 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err)
{
struct sock *sk;
struct sock *sk = chan->sk;
struct l2cap_disconn_req req;
if (!conn)
return;
sk = chan->sk;
if (chan->mode == L2CAP_MODE_ERTM) {
__clear_retrans_timer(chan);
__clear_monitor_timer(chan);
......@@ -733,56 +742,47 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_DISCONN_REQ, sizeof(req), &req);
l2cap_state_change(chan, BT_DISCONN);
sk->sk_err = err;
lock_sock(sk);
__l2cap_state_change(chan, BT_DISCONN);
__l2cap_chan_set_err(chan, err);
release_sock(sk);
}
/* ---- L2CAP connections ---- */
static void l2cap_conn_start(struct l2cap_conn *conn)
{
struct l2cap_chan *chan;
struct l2cap_chan *chan, *tmp;
BT_DBG("conn %p", conn);
rcu_read_lock();
mutex_lock(&conn->chan_lock);
list_for_each_entry_rcu(chan, &conn->chan_l, list) {
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
struct sock *sk = chan->sk;
bh_lock_sock(sk);
l2cap_chan_lock(chan);
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
if (chan->state == BT_CONNECT) {
struct l2cap_conn_req req;
if (!l2cap_chan_check_security(chan) ||
!__l2cap_no_conn_pending(chan)) {
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
&& test_bit(CONF_STATE2_DEVICE,
&chan->conf_state)) {
/* l2cap_chan_close() calls list_del(chan)
* so release the lock */
l2cap_chan_close(chan, ECONNRESET);
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
set_bit(CONF_CONNECT_PEND, &chan->conf_state);
l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ,
sizeof(req), &req);
l2cap_send_conn_req(chan);
} else if (chan->state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
......@@ -791,6 +791,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_chan_check_security(chan)) {
lock_sock(sk);
if (bt_sk(sk)->defer_setup) {
struct sock *parent = bt_sk(sk)->parent;
rsp.result = cpu_to_le16(L2CAP_CR_PEND);
......@@ -799,10 +800,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
parent->sk_data_ready(parent, 0);
} else {
l2cap_state_change(chan, BT_CONFIG);
__l2cap_state_change(chan, BT_CONFIG);
rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
}
release_sock(sk);
} else {
rsp.result = cpu_to_le16(L2CAP_CR_PEND);
rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
......@@ -813,7 +815,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
rsp.result != L2CAP_CR_SUCCESS) {
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
......@@ -823,10 +825,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
chan->num_conf_req++;
}
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
}
rcu_read_unlock();
mutex_unlock(&conn->chan_lock);
}
/* Find socket with cid and source bdaddr.
......@@ -902,28 +904,34 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
__set_chan_timer(chan, sk->sk_sndtimeo);
l2cap_state_change(chan, BT_CONNECTED);
__l2cap_state_change(chan, BT_CONNECTED);
parent->sk_data_ready(parent, 0);
clean:
release_sock(parent);
}
static void l2cap_chan_ready(struct sock *sk)
static void l2cap_chan_ready(struct l2cap_chan *chan)
{
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sock *parent = bt_sk(sk)->parent;
struct sock *sk = chan->sk;
struct sock *parent;
lock_sock(sk);
parent = bt_sk(sk)->parent;
BT_DBG("sk %p, parent %p", sk, parent);
chan->conf_state = 0;
__clear_chan_timer(chan);
l2cap_state_change(chan, BT_CONNECTED);
__l2cap_state_change(chan, BT_CONNECTED);
sk->sk_state_change(sk);
if (parent)
parent->sk_data_ready(parent, 0);
release_sock(sk);
}
static void l2cap_conn_ready(struct l2cap_conn *conn)
......@@ -938,29 +946,31 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
if (conn->hcon->out && conn->hcon->type == LE_LINK)
smp_conn_security(conn, conn->hcon->pending_sec_level);
rcu_read_lock();
mutex_lock(&conn->chan_lock);
list_for_each_entry_rcu(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
list_for_each_entry(chan, &conn->chan_l, list) {
bh_lock_sock(sk);
l2cap_chan_lock(chan);
if (conn->hcon->type == LE_LINK) {
if (smp_conn_security(conn, chan->sec_level))
l2cap_chan_ready(sk);
l2cap_chan_ready(chan);
} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
struct sock *sk = chan->sk;
__clear_chan_timer(chan);
l2cap_state_change(chan, BT_CONNECTED);
lock_sock(sk);
__l2cap_state_change(chan, BT_CONNECTED);
sk->sk_state_change(sk);
release_sock(sk);
} else if (chan->state == BT_CONNECT)
l2cap_do_start(chan);
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
}
rcu_read_unlock();
mutex_unlock(&conn->chan_lock);
}
/* Notify sockets that we cannot guaranty reliability anymore */
......@@ -970,16 +980,14 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
BT_DBG("conn %p", conn);
rcu_read_lock();
list_for_each_entry_rcu(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
mutex_lock(&conn->chan_lock);
list_for_each_entry(chan, &conn->chan_l, list) {
if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
sk->sk_err = err;
__l2cap_chan_set_err(chan, err);
}
rcu_read_unlock();
mutex_unlock(&conn->chan_lock);
}
static void l2cap_info_timeout(struct work_struct *work)
......@@ -997,7 +1005,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
{
struct l2cap_conn *conn = hcon->l2cap_data;
struct l2cap_chan *chan, *l;
struct sock *sk;
if (!conn)
return;
......@@ -1006,21 +1013,27 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree_skb(conn->rx_skb);
mutex_lock(&conn->chan_lock);
/* Kill channels */
list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
sk = chan->sk;
lock_sock(sk);
l2cap_chan_lock(chan);
l2cap_chan_del(chan, err);
release_sock(sk);
l2cap_chan_unlock(chan);
chan->ops->close(chan->data);
}
mutex_unlock(&conn->chan_lock);
hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
cancel_delayed_work_sync(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) {
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
......@@ -1072,6 +1085,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->feat_mask = 0;
spin_lock_init(&conn->lock);
mutex_init(&conn->chan_lock);
INIT_LIST_HEAD(&conn->chan_l);
......@@ -1139,7 +1153,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
hci_dev_lock(hdev);
lock_sock(sk);
l2cap_chan_lock(chan);
/* PSM must be odd and lsb of upper byte must be 0 */
if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
......@@ -1166,17 +1180,21 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
goto done;
}
lock_sock(sk);
switch (sk->sk_state) {
case BT_CONNECT:
case BT_CONNECT2:
case BT_CONFIG:
/* Already connecting */
err = 0;
release_sock(sk);
goto done;
case BT_CONNECTED:
/* Already connected */
err = -EISCONN;
release_sock(sk);
goto done;
case BT_OPEN:
......@@ -1186,11 +1204,15 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
default:
err = -EBADFD;
release_sock(sk);
goto done;
}
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, dst);
release_sock(sk);
chan->psm = psm;
chan->dcid = cid;
......@@ -1218,7 +1240,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
/* Update source addr of the socket */
bacpy(src, conn->src);
l2cap_chan_unlock(chan);
l2cap_chan_add(conn, chan);
l2cap_chan_lock(chan);
l2cap_state_change(chan, BT_CONNECT);
__set_chan_timer(chan, sk->sk_sndtimeo);
......@@ -1235,6 +1259,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
err = 0;
done:
l2cap_chan_unlock(chan);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
......@@ -1276,14 +1301,14 @@ static void l2cap_monitor_timeout(struct work_struct *work)
{
struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
monitor_timer.work);
struct sock *sk = chan->sk;
BT_DBG("chan %p", chan);
lock_sock(sk);
l2cap_chan_lock(chan);
if (chan->retry_count >= chan->remote_max_tx) {
l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
release_sock(sk);
l2cap_chan_unlock(chan);
return;
}
......@@ -1291,25 +1316,26 @@ static void l2cap_monitor_timeout(struct work_struct *work)
__set_monitor_timer(chan);
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
release_sock(sk);
l2cap_chan_unlock(chan);
}
static void l2cap_retrans_timeout(struct work_struct *work)
{
struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
retrans_timer.work);
struct sock *sk = chan->sk;
BT_DBG("chan %p", chan);
lock_sock(sk);
l2cap_chan_lock(chan);
chan->retry_count = 1;
__set_monitor_timer(chan);
set_bit(CONN_WAIT_F, &chan->conn_state);
l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
release_sock(sk);
l2cap_chan_unlock(chan);
}
static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
......@@ -1450,17 +1476,19 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
if (bt_cb(skb)->retries == 1)
if (bt_cb(skb)->retries == 1) {
chan->unacked_frames++;
if (!nsent++)
__clear_ack_timer(chan);
}
chan->frames_sent++;
if (skb_queue_is_last(&chan->tx_q, skb))
chan->tx_send_head = NULL;
else
chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
nsent++;
}
return nsent;
......@@ -1478,7 +1506,7 @@ static int l2cap_retransmit_frames(struct l2cap_chan *chan)
return ret;
}
static void l2cap_send_ack(struct l2cap_chan *chan)
static void __l2cap_send_ack(struct l2cap_chan *chan)
{
u32 control = 0;
......@@ -1498,6 +1526,12 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
l2cap_send_sframe(chan, control);
}
static void l2cap_send_ack(struct l2cap_chan *chan)
{
__clear_ack_timer(chan);
__l2cap_send_ack(chan);
}
static void l2cap_send_srejtail(struct l2cap_chan *chan)
{
struct srej_list *tail;
......@@ -1512,9 +1546,11 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)
l2cap_send_sframe(chan, control);
}
static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
struct msghdr *msg, int len,
int count, struct sk_buff *skb)
{
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
struct l2cap_conn *conn = chan->conn;
struct sk_buff **frag;
int err, sent = 0;
......@@ -1529,7 +1565,10 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in
while (len) {
count = min_t(unsigned int, conn->mtu, len);
*frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
*frag = chan->ops->alloc_skb(chan, count,
msg->msg_flags & MSG_DONTWAIT,
&err);
if (!*frag)
return err;
if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
......@@ -1550,17 +1589,18 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
{
struct sock *sk = chan->sk;
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("sk %p len %d priority %u", sk, (int)len, priority);
BT_DBG("chan %p len %d priority %u", chan, (int)len, priority);
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
skb = chan->ops->alloc_skb(chan, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return ERR_PTR(err);
......@@ -1572,7 +1612,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
put_unaligned_le16(chan->psm, skb_put(skb, 2));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
if (unlikely(err < 0)) {
kfree_skb(skb);
return ERR_PTR(err);
......@@ -1584,17 +1624,18 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 priority)
{
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen = L2CAP_HDR_SIZE;
struct l2cap_hdr *lh;
BT_DBG("sk %p len %d", sk, (int)len);
BT_DBG("chan %p len %d", chan, (int)len);
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
skb = chan->ops->alloc_skb(chan, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return ERR_PTR(err);
......@@ -1605,7 +1646,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
if (unlikely(err < 0)) {
kfree_skb(skb);
return ERR_PTR(err);
......@@ -1617,13 +1658,12 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
struct msghdr *msg, size_t len,
u32 control, u16 sdulen)
{
struct sock *sk = chan->sk;
struct l2cap_conn *conn = chan->conn;
struct sk_buff *skb;
int err, count, hlen;
struct l2cap_hdr *lh;
BT_DBG("sk %p len %d", sk, (int)len);
BT_DBG("chan %p len %d", chan, (int)len);
if (!conn)
return ERR_PTR(-ENOTCONN);
......@@ -1640,8 +1680,10 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
hlen += L2CAP_FCS_SIZE;
count = min_t(unsigned int, (conn->mtu - hlen), len);
skb = bt_skb_send_alloc(sk, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
skb = chan->ops->alloc_skb(chan, count + hlen,
msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return ERR_PTR(err);
......@@ -1655,7 +1697,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
if (sdulen)
put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
if (unlikely(err < 0)) {
kfree_skb(skb);
return ERR_PTR(err);
......@@ -1801,9 +1843,9 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
BT_DBG("conn %p", conn);
rcu_read_lock();
mutex_lock(&conn->chan_lock);
list_for_each_entry_rcu(chan, &conn->chan_l, list) {
list_for_each_entry(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
if (chan->chan_type != L2CAP_CHAN_RAW)
continue;
......@@ -1819,7 +1861,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
kfree_skb(nskb);
}
rcu_read_unlock();
mutex_unlock(&conn->chan_lock);
}
/* ---- L2CAP signalling commands ---- */
......@@ -1987,9 +2029,13 @@ static void l2cap_ack_timeout(struct work_struct *work)
BT_DBG("chan %p", chan);
lock_sock(chan->sk);
l2cap_send_ack(chan);
release_sock(chan->sk);
l2cap_chan_lock(chan);
__l2cap_send_ack(chan);
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
}
static inline void l2cap_ertm_init(struct l2cap_chan *chan)
......@@ -2607,6 +2653,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
parent = pchan->sk;
mutex_lock(&conn->chan_lock);
lock_sock(parent);
/* Check if the ACL is secure enough (if not SDP) */
......@@ -2647,7 +2694,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
bt_accept_enqueue(parent, sk);
l2cap_chan_add(conn, chan);
__l2cap_chan_add(conn, chan);
dcid = chan->scid;
......@@ -2658,28 +2705,29 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_chan_check_security(chan)) {
if (bt_sk(sk)->defer_setup) {
l2cap_state_change(chan, BT_CONNECT2);
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
parent->sk_data_ready(parent, 0);
} else {
l2cap_state_change(chan, BT_CONFIG);
__l2cap_state_change(chan, BT_CONFIG);
result = L2CAP_CR_SUCCESS;
status = L2CAP_CS_NO_INFO;
}
} else {
l2cap_state_change(chan, BT_CONNECT2);
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHEN_PEND;
}
} else {
l2cap_state_change(chan, BT_CONNECT2);
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_NO_INFO;
}
response:
release_sock(parent);
mutex_unlock(&conn->chan_lock);
sendresp:
rsp.scid = cpu_to_le16(scid);
......@@ -2695,8 +2743,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
conn->info_ident = l2cap_get_ident(conn);
schedule_delayed_work(&conn->info_timer,
msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
l2cap_send_cmd(conn, conn->info_ident,
L2CAP_INFO_REQ, sizeof(info), &info);
......@@ -2719,27 +2766,36 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
u16 scid, dcid, result, status;
struct l2cap_chan *chan;
struct sock *sk;
u8 req[128];
int err;
scid = __le16_to_cpu(rsp->scid);
dcid = __le16_to_cpu(rsp->dcid);
result = __le16_to_cpu(rsp->result);
status = __le16_to_cpu(rsp->status);
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
dcid, scid, result, status);
mutex_lock(&conn->chan_lock);
if (scid) {
chan = l2cap_get_chan_by_scid(conn, scid);
if (!chan)
return -EFAULT;
chan = __l2cap_get_chan_by_scid(conn, scid);
if (!chan) {
err = -EFAULT;
goto unlock;
}
} else {
chan = l2cap_get_chan_by_ident(conn, cmd->ident);
if (!chan)
return -EFAULT;
chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
if (!chan) {
err = -EFAULT;
goto unlock;
}
}
sk = chan->sk;
err = 0;
l2cap_chan_lock(chan);
switch (result) {
case L2CAP_CR_SUCCESS:
......@@ -2765,8 +2821,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
break;
}
release_sock(sk);
return 0;
l2cap_chan_unlock(chan);
unlock:
mutex_unlock(&conn->chan_lock);
return err;
}
static inline void set_default_fcs(struct l2cap_chan *chan)
......@@ -2786,7 +2846,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
u16 dcid, flags;
u8 rsp[64];
struct l2cap_chan *chan;
struct sock *sk;
int len;
dcid = __le16_to_cpu(req->dcid);
......@@ -2798,7 +2857,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!chan)
return -ENOENT;
sk = chan->sk;
l2cap_chan_lock(chan);
if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
struct l2cap_cmd_rej_cid rej;
......@@ -2860,7 +2919,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (chan->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
l2cap_chan_ready(chan);
goto unlock;
}
......@@ -2887,7 +2946,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
}
unlock:
release_sock(sk);
l2cap_chan_unlock(chan);
return 0;
}
......@@ -2896,7 +2955,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
struct l2cap_chan *chan;
struct sock *sk;
int len = cmd->len - sizeof(*rsp);
scid = __le16_to_cpu(rsp->scid);
......@@ -2910,7 +2968,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!chan)
return 0;
sk = chan->sk;
l2cap_chan_lock(chan);
switch (result) {
case L2CAP_CONF_SUCCESS:
......@@ -2969,9 +3027,9 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
}
default:
sk->sk_err = ECONNRESET;
__set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
l2cap_chan_set_err(chan, ECONNRESET);
__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
......@@ -2991,11 +3049,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (chan->mode == L2CAP_MODE_ERTM)
l2cap_ertm_init(chan);
l2cap_chan_ready(sk);
l2cap_chan_ready(chan);
}
done:
release_sock(sk);
l2cap_chan_unlock(chan);
return 0;
}
......@@ -3012,9 +3070,15 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
chan = l2cap_get_chan_by_scid(conn, dcid);
if (!chan)
mutex_lock(&conn->chan_lock);
chan = __l2cap_get_chan_by_scid(conn, dcid);
if (!chan) {
mutex_unlock(&conn->chan_lock);
return 0;
}
l2cap_chan_lock(chan);
sk = chan->sk;
......@@ -3022,12 +3086,18 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
rsp.scid = cpu_to_le16(chan->dcid);
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
lock_sock(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
release_sock(sk);
l2cap_chan_del(chan, ECONNRESET);
release_sock(sk);
l2cap_chan_unlock(chan);
chan->ops->close(chan->data);
mutex_unlock(&conn->chan_lock);
return 0;
}
......@@ -3036,23 +3106,30 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
u16 dcid, scid;
struct l2cap_chan *chan;
struct sock *sk;
scid = __le16_to_cpu(rsp->scid);
dcid = __le16_to_cpu(rsp->dcid);
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
chan = l2cap_get_chan_by_scid(conn, scid);
if (!chan)
mutex_lock(&conn->chan_lock);
chan = __l2cap_get_chan_by_scid(conn, scid);
if (!chan) {
mutex_unlock(&conn->chan_lock);
return 0;
}
sk = chan->sk;
l2cap_chan_lock(chan);
l2cap_chan_del(chan, 0);
release_sock(sk);
l2cap_chan_unlock(chan);
chan->ops->close(chan->data);
mutex_unlock(&conn->chan_lock);
return 0;
}
......@@ -3132,7 +3209,8 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
return 0;
}
if (type == L2CAP_IT_FEAT_MASK) {
switch (type) {
case L2CAP_IT_FEAT_MASK:
conn->feat_mask = get_unaligned_le32(rsp->data);
if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
......@@ -3149,11 +3227,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
l2cap_conn_start(conn);
}
} else if (type == L2CAP_IT_FIXED_CHAN) {
break;
case L2CAP_IT_FIXED_CHAN:
conn->fixed_chan_mask = rsp->data[0];
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
l2cap_conn_start(conn);
break;
}
return 0;
......@@ -3713,19 +3795,11 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u3
static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
{
u32 control;
BT_DBG("chan %p, Enter local busy", chan);
set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
control = __set_reqseq(chan, chan->buffer_seq);
control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
l2cap_send_sframe(chan, control);
set_bit(CONN_RNR_SENT, &chan->conn_state);
__clear_ack_timer(chan);
__set_ack_timer(chan);
}
static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan)
......@@ -3865,8 +3939,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
goto drop;
}
if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
if (!test_bit(CONN_RNR_SENT, &chan->conn_state))
l2cap_send_ack(chan);
goto drop;
}
if (tx_seq == chan->expected_tx_seq)
goto expected;
......@@ -3927,15 +4004,15 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
__skb_queue_head_init(&chan->srej_q);
l2cap_add_to_srej_queue(chan, skb, tx_seq, sar);
set_bit(CONN_SEND_PBIT, &chan->conn_state);
/* Set P-bit only if there are some I-frames to ack. */
if (__clear_ack_timer(chan))
set_bit(CONN_SEND_PBIT, &chan->conn_state);
err = l2cap_send_srejframe(chan, tx_seq);
if (err < 0) {
l2cap_send_disconn_req(chan->conn, chan, -err);
return err;
}
__clear_ack_timer(chan);
}
return 0;
......@@ -4135,9 +4212,8 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_cont
return 0;
}
static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
static int l2cap_ertm_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
{
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
u32 control;
u16 req_seq;
int len, next_tx_seq_offset, req_seq_offset;
......@@ -4205,7 +4281,6 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb)
static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
{
struct l2cap_chan *chan;
struct sock *sk = NULL;
u32 control;
u16 tx_seq;
int len;
......@@ -4213,10 +4288,12 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
chan = l2cap_get_chan_by_scid(conn, cid);
if (!chan) {
BT_DBG("unknown cid 0x%4.4x", cid);
goto drop;
/* Drop packet and return */
kfree_skb(skb);
return 0;
}
sk = chan->sk;
l2cap_chan_lock(chan);
BT_DBG("chan %p, len %d", chan, skb->len);
......@@ -4238,7 +4315,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
break;
case L2CAP_MODE_ERTM:
l2cap_ertm_data_rcv(sk, skb);
l2cap_ertm_data_rcv(chan, skb);
goto done;
......@@ -4287,26 +4364,20 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
kfree_skb(skb);
done:
if (sk)
release_sock(sk);
l2cap_chan_unlock(chan);
return 0;
}
static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
{
struct sock *sk = NULL;
struct l2cap_chan *chan;
chan = l2cap_global_chan_by_psm(0, psm, conn->src);
if (!chan)
goto drop;
sk = chan->sk;
lock_sock(sk);
BT_DBG("sk %p, len %d", sk, skb->len);
BT_DBG("chan %p, len %d", chan, skb->len);
if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
goto drop;
......@@ -4315,31 +4386,23 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
goto drop;
if (!chan->ops->recv(chan->data, skb))
goto done;
return 0;
drop:
kfree_skb(skb);
done:
if (sk)
release_sock(sk);
return 0;
}
static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
{
struct sock *sk = NULL;
struct l2cap_chan *chan;
chan = l2cap_global_chan_by_scid(0, cid, conn->src);
if (!chan)
goto drop;
sk = chan->sk;
lock_sock(sk);
BT_DBG("sk %p, len %d", sk, skb->len);
BT_DBG("chan %p, len %d", chan, skb->len);
if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
goto drop;
......@@ -4348,14 +4411,11 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct
goto drop;
if (!chan->ops->recv(chan->data, skb))
goto done;
return 0;
drop:
kfree_skb(skb);
done:
if (sk)
release_sock(sk);
return 0;
}
......@@ -4479,8 +4539,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
if (encrypt == 0x00) {
if (chan->sec_level == BT_SECURITY_MEDIUM) {
__clear_chan_timer(chan);
__set_chan_timer(chan,
msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
} else if (chan->sec_level == BT_SECURITY_HIGH)
l2cap_chan_close(chan, ECONNREFUSED);
} else {
......@@ -4504,57 +4563,49 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();
list_for_each_entry_rcu(chan, &conn->chan_l, list) {
struct sock *sk = chan->sk;
mutex_lock(&conn->chan_lock);
bh_lock_sock(sk);
list_for_each_entry(chan, &conn->chan_l, list) {
l2cap_chan_lock(chan);
BT_DBG("chan->scid %d", chan->scid);
if (chan->scid == L2CAP_CID_LE_DATA) {
if (!status && encrypt) {
chan->sec_level = hcon->sec_level;
l2cap_chan_ready(sk);
l2cap_chan_ready(chan);
}
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) {
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
if (!status && (chan->state == BT_CONNECTED ||
chan->state == BT_CONFIG)) {
l2cap_check_encryption(chan, encrypt);
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
continue;
}
if (chan->state == BT_CONNECT) {
if (!status) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(chan->scid);
req.psm = chan->psm;
chan->ident = l2cap_get_ident(conn);
set_bit(CONF_CONNECT_PEND, &chan->conf_state);
l2cap_send_cmd(conn, chan->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
l2cap_send_conn_req(chan);
} else {
__clear_chan_timer(chan);
__set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
}
} else if (chan->state == BT_CONNECT2) {
struct sock *sk = chan->sk;
struct l2cap_conn_rsp rsp;
__u16 res, stat;
lock_sock(sk);
if (!status) {
if (bt_sk(sk)->defer_setup) {
struct sock *parent = bt_sk(sk)->parent;
......@@ -4563,18 +4614,19 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (parent)
parent->sk_data_ready(parent, 0);
} else {
l2cap_state_change(chan, BT_CONFIG);
__l2cap_state_change(chan, BT_CONFIG);
res = L2CAP_CR_SUCCESS;
stat = L2CAP_CS_NO_INFO;
}
} else {
l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan,
msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
__l2cap_state_change(chan, BT_DISCONN);
__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
release_sock(sk);
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = cpu_to_le16(res);
......@@ -4583,10 +4635,10 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
sizeof(rsp), &rsp);
}
bh_unlock_sock(sk);
l2cap_chan_unlock(chan);
}
rcu_read_unlock();
mutex_unlock(&conn->chan_lock);
return 0;
}
......@@ -4647,6 +4699,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
if (chan && chan->sk) {
struct sock *sk = chan->sk;
lock_sock(sk);
if (chan->imtu < len - L2CAP_HDR_SIZE) {
BT_ERR("Frame exceeding recv MTU (len %d, "
......@@ -4717,7 +4770,7 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
c->state, __le16_to_cpu(c->psm),
c->scid, c->dcid, c->imtu, c->omtu,
c->sec_level, c->mode);
}
}
read_unlock(&chan_list_lock);
......
......@@ -125,13 +125,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
if (err)
goto done;
return err;
lock_sock(sk);
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
done:
if (sock_owned_by_user(sk))
release_sock(sk);
release_sock(sk);
return err;
}
......@@ -783,7 +785,7 @@ static void l2cap_sock_kill(struct sock *sk)
if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
return;
BT_DBG("sk %p state %d", sk, sk->sk_state);
BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
/* Kill poor orphan */
......@@ -795,7 +797,8 @@ static void l2cap_sock_kill(struct sock *sk)
static int l2cap_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_chan *chan;
struct l2cap_conn *conn;
int err = 0;
BT_DBG("sock %p, sk %p", sock, sk);
......@@ -803,13 +806,24 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
if (!sk)
return 0;
chan = l2cap_pi(sk)->chan;
conn = chan->conn;
if (conn)
mutex_lock(&conn->chan_lock);
l2cap_chan_lock(chan);
lock_sock(sk);
if (!sk->sk_shutdown) {
if (chan->mode == L2CAP_MODE_ERTM)
err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
release_sock(sk);
l2cap_chan_close(chan, 0);
lock_sock(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
err = bt_sock_wait_state(sk, BT_CLOSED,
......@@ -820,6 +834,11 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = -sk->sk_err;
release_sock(sk);
l2cap_chan_unlock(chan);
if (conn)
mutex_unlock(&conn->chan_lock);
return err;
}
......@@ -862,8 +881,12 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
struct sock *sk = data;
struct l2cap_pinfo *pi = l2cap_pi(sk);
if (pi->rx_busy_skb)
return -ENOMEM;
lock_sock(sk);
if (pi->rx_busy_skb) {
err = -ENOMEM;
goto done;
}
err = sock_queue_rcv_skb(sk, skb);
......@@ -882,6 +905,9 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
err = 0;
}
done:
release_sock(sk);
return err;
}
......@@ -899,12 +925,22 @@ static void l2cap_sock_state_change_cb(void *data, int state)
sk->sk_state = state;
}
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb,
int *err)
{
struct sock *sk = chan->sk;
return bt_skb_send_alloc(sk, len, nb, err);
}
static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
.recv = l2cap_sock_recv_cb,
.close = l2cap_sock_close_cb,
.state_change = l2cap_sock_state_change_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb,
};
static void l2cap_sock_destruct(struct sock *sk)
......@@ -1004,7 +1040,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
sock_reset_flag(sk, SOCK_ZAPPED);
......
......@@ -24,6 +24,8 @@
/* Bluetooth kernel library. */
#define pr_fmt(fmt) "Bluetooth: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
......@@ -151,7 +153,26 @@ int bt_to_errno(__u16 code)
}
EXPORT_SYMBOL(bt_to_errno);
int bt_printk(const char *level, const char *format, ...)
int bt_info(const char *format, ...)
{
struct va_format vaf;
va_list args;
int r;
va_start(args, format);
vaf.fmt = format;
vaf.va = &args;
r = pr_info("%pV", &vaf);
va_end(args);
return r;
}
EXPORT_SYMBOL(bt_info);
int bt_err(const char *format, ...)
{
struct va_format vaf;
va_list args;
......@@ -162,10 +183,10 @@ int bt_printk(const char *level, const char *format, ...)
vaf.fmt = format;
vaf.va = &args;
r = printk("%sBluetooth: %pV\n", level, &vaf);
r = pr_err("%pV", &vaf);
va_end(args);
return r;
}
EXPORT_SYMBOL(bt_printk);
EXPORT_SYMBOL(bt_err);
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -196,7 +196,7 @@ static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev, *entry;
struct list_head *head = &rfcomm_dev_list, *p;
struct list_head *head = &rfcomm_dev_list;
int err = 0;
BT_DBG("id %d channel %d", req->dev_id, req->channel);
......@@ -215,7 +215,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
break;
dev->id++;
head = p;
head = &entry->list;
}
} else {
dev->id = req->dev_id;
......@@ -229,7 +229,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
if (entry->id > dev->id - 1)
break;
head = p;
head = &entry->list;
}
}
......
......@@ -29,7 +29,7 @@
#include <linux/scatterlist.h>
#include <crypto/b128ops.h>
#define SMP_TIMEOUT 30000 /* 30 seconds */
#define SMP_TIMEOUT msecs_to_jiffies(30000)
static inline void swap128(u8 src[16], u8 dst[16])
{
......@@ -186,8 +186,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
hci_send_acl(conn->hchan, skb, 0);
cancel_delayed_work_sync(&conn->security_timer);
schedule_delayed_work(&conn->security_timer,
msecs_to_jiffies(SMP_TIMEOUT));
schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT);
}
static __u8 authreq_to_seclevel(__u8 authreq)
......@@ -217,7 +216,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
{
u8 dist_keys = 0;
if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) {
if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
dist_keys = SMP_DIST_ENC_KEY;
authreq |= SMP_AUTH_BONDING;
} else {
......@@ -250,21 +249,27 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
(max_key_size < SMP_MIN_ENC_KEY_SIZE))
return SMP_ENC_KEY_SIZE;
smp->smp_key_size = max_key_size;
smp->enc_key_size = max_key_size;
return 0;
}
static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
{
struct hci_conn *hcon = conn->hcon;
if (send)
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason);
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
hcon->dst_type, reason);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
}
#define JUST_WORKS 0x00
......@@ -305,7 +310,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
remote_io > SMP_IO_KEYBOARD_DISPLAY)
method = JUST_WORKS;
else
method = gen_method[local_io][remote_io];
method = gen_method[remote_io][local_io];
/* If not bonding, don't ask user to confirm a Zero TK */
if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)
......@@ -346,9 +351,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
hci_dev_lock(hcon->hdev);
if (method == REQ_PASSKEY)
ret = mgmt_user_passkey_request(hcon->hdev, conn->dst);
ret = mgmt_user_passkey_request(hcon->hdev, conn->dst,
hcon->type, hcon->dst_type);
else
ret = mgmt_user_confirm_request(hcon->hdev, conn->dst,
hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0);
hci_dev_unlock(hcon->hdev);
......@@ -377,12 +384,11 @@ static void confirm_work(struct work_struct *work)
if (conn->hcon->out)
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, 0,
conn->src, conn->hcon->dst_type, conn->dst,
res);
conn->src, conn->hcon->dst_type, conn->dst, res);
else
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->dst_type, conn->dst, 0, conn->src,
res);
conn->hcon->dst_type, conn->dst, 0, conn->src,
res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
......@@ -417,12 +423,10 @@ static void random_work(struct work_struct *work)
if (hcon->out)
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0,
conn->src, hcon->dst_type, conn->dst,
res);
conn->src, hcon->dst_type, conn->dst, res);
else
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->dst_type, conn->dst, 0, conn->src,
res);
hcon->dst_type, conn->dst, 0, conn->src, res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
......@@ -446,16 +450,16 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key);
swap128(key, stk);
memset(stk + smp->smp_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) {
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) {
reason = SMP_UNSPECIFIED;
goto error;
}
hci_le_start_enc(hcon, ediv, rand, stk);
hcon->enc_key_size = smp->smp_key_size;
hcon->enc_key_size = smp->enc_key_size;
} else {
u8 stk[16], r[16], rand[8];
__le16 ediv;
......@@ -469,11 +473,12 @@ static void random_work(struct work_struct *work)
smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key);
swap128(key, stk);
memset(stk + smp->smp_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->smp_key_size);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
hci_add_ltk(hcon->hdev, 0, conn->dst, smp->smp_key_size,
ediv, rand, stk);
hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size,
ediv, rand);
}
return;
......@@ -506,7 +511,7 @@ void smp_chan_destroy(struct l2cap_conn *conn)
{
struct smp_chan *smp = conn->smp_chan;
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend);
BUG_ON(!smp);
if (smp->tfm)
crypto_free_blkcipher(smp->tfm);
......@@ -571,7 +576,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (conn->hcon->link_mode & HCI_LM_MASTER)
return SMP_CMD_NOTSUPP;
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend))
if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
smp = smp_chan_create(conn);
smp = conn->smp_chan;
......@@ -584,6 +589,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (req->auth_req & SMP_AUTH_BONDING)
auth = req->auth_req;
conn->hcon->pending_sec_level = authreq_to_seclevel(auth);
build_pairing_cmd(conn, req, &rsp, auth);
key_size = min(req->max_key_size, rsp.max_key_size);
......@@ -698,23 +705,18 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
struct link_key *key;
struct key_master_id *master;
struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
key = hci_find_link_key_type(hcon->hdev, conn->dst,
HCI_LK_SMP_LTK);
key = hci_find_ltk_by_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND,
&hcon->pend))
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1;
master = (void *) key->data;
hci_le_start_enc(hcon, master->ediv, master->rand,
key->val);
hcon->enc_key_size = key->pin_len;
hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
hcon->enc_key_size = key->enc_size;
return 1;
......@@ -733,7 +735,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (smp_ltk_encrypt(conn))
return 0;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend))
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
smp = smp_chan_create(conn);
......@@ -772,7 +774,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
if (smp_ltk_encrypt(conn))
goto done;
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend))
if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
return 0;
smp = smp_chan_create(conn);
......@@ -817,13 +819,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
struct hci_dev *hdev = conn->hcon->hdev;
struct hci_conn *hcon = conn->hcon;
u8 authenticated;
skb_pull(skb, sizeof(*rp));
hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
rp->ediv, rp->rand, smp->tk);
hci_dev_lock(hdev);
authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_LTK, 1, authenticated, smp->tk, smp->enc_key_size,
rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
hci_dev_unlock(hdev);
return 0;
}
......@@ -908,7 +916,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
BT_DBG("conn %p force %d", conn, force);
if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend))
if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
return 0;
rsp = (void *) &smp->prsp[1];
......@@ -933,6 +941,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
struct hci_conn *hcon = conn->hcon;
u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
......@@ -941,8 +951,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size,
ediv, ident.rand, enc.ltk);
authenticated = hcon->sec_level == BT_SECURITY_HIGH;
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
HCI_SMP_LTK_SLAVE, 1, authenticated,
enc.ltk, smp->enc_key_size, ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
......@@ -982,7 +994,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
}
if (conn->hcon->out || force) {
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend);
clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment