Commit 370c5ace authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents 7eb2450a 40b552aa
...@@ -89,6 +89,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -89,6 +89,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0) }, { USB_DEVICE(0x0b05, 0x17d0) },
{ USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x3005) },
{ USB_DEVICE(0x0CF3, 0x3008) }, { USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) }, { USB_DEVICE(0x0CF3, 0x311E) },
...@@ -137,6 +138,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -137,6 +138,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
...@@ -180,10 +182,9 @@ static int ath3k_load_firmware(struct usb_device *udev, ...@@ -180,10 +182,9 @@ static int ath3k_load_firmware(struct usb_device *udev,
} }
memcpy(send_buf, firmware->data, 20); memcpy(send_buf, firmware->data, 20);
if ((err = usb_control_msg(udev, pipe, err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR,
USB_REQ_DFU_DNLOAD, 0, 0, send_buf, 20, USB_CTRL_SET_TIMEOUT);
USB_TYPE_VENDOR, 0, 0, if (err < 0) {
send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
BT_ERR("Can't change to loading configuration err"); BT_ERR("Can't change to loading configuration err");
goto error; goto error;
} }
...@@ -366,7 +367,7 @@ static int ath3k_load_patch(struct usb_device *udev) ...@@ -366,7 +367,7 @@ static int ath3k_load_patch(struct usb_device *udev)
} }
snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
fw_version.rom_version); le32_to_cpu(fw_version.rom_version));
ret = request_firmware(&firmware, filename, &udev->dev); ret = request_firmware(&firmware, filename, &udev->dev);
if (ret < 0) { if (ret < 0) {
...@@ -428,7 +429,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) ...@@ -428,7 +429,7 @@ static int ath3k_load_syscfg(struct usb_device *udev)
} }
snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
fw_version.rom_version, clk_value, ".dfu"); le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
ret = request_firmware(&firmware, filename, &udev->dev); ret = request_firmware(&firmware, filename, &udev->dev);
if (ret < 0) { if (ret < 0) {
......
...@@ -131,8 +131,11 @@ static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb) ...@@ -131,8 +131,11 @@ static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)
BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);
if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) if (!urb) {
return -ENOMEM; urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
}
pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
...@@ -218,8 +221,11 @@ static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) ...@@ -218,8 +221,11 @@ static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)
BT_DBG("bfusb %p urb %p", data, urb); BT_DBG("bfusb %p urb %p", data, urb);
if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) if (!urb) {
return -ENOMEM; urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
}
skb = bt_skb_alloc(size, GFP_ATOMIC); skb = bt_skb_alloc(size, GFP_ATOMIC);
if (!skb) { if (!skb) {
......
...@@ -257,7 +257,8 @@ static void bluecard_write_wakeup(bluecard_info_t *info) ...@@ -257,7 +257,8 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
ready_bit = XMIT_BUF_ONE_READY; ready_bit = XMIT_BUF_ONE_READY;
} }
if (!(skb = skb_dequeue(&(info->txq)))) skb = skb_dequeue(&(info->txq));
if (!skb)
break; break;
if (bt_cb(skb)->pkt_type & 0x80) { if (bt_cb(skb)->pkt_type & 0x80) {
...@@ -391,7 +392,8 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) ...@@ -391,7 +392,8 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_skb == NULL) { if (info->rx_skb == NULL) {
info->rx_state = RECV_WAIT_PACKET_TYPE; info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0; info->rx_count = 0;
if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!info->rx_skb) {
BT_ERR("Can't allocate mem for new packet"); BT_ERR("Can't allocate mem for new packet");
return; return;
} }
...@@ -566,7 +568,8 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) ...@@ -566,7 +568,8 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
/* Ericsson baud rate command */ /* Ericsson baud rate command */
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 }; unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
if (!(skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!skb) {
BT_ERR("Can't allocate mem for new packet"); BT_ERR("Can't allocate mem for new packet");
return -1; return -1;
} }
......
...@@ -193,8 +193,8 @@ static void bt3c_write_wakeup(bt3c_info_t *info) ...@@ -193,8 +193,8 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
if (!pcmcia_dev_present(info->p_dev)) if (!pcmcia_dev_present(info->p_dev))
break; break;
skb = skb_dequeue(&(info->txq));
if (!(skb = skb_dequeue(&(info->txq)))) { if (!skb) {
clear_bit(XMIT_SENDING, &(info->tx_state)); clear_bit(XMIT_SENDING, &(info->tx_state));
break; break;
} }
...@@ -238,7 +238,8 @@ static void bt3c_receive(bt3c_info_t *info) ...@@ -238,7 +238,8 @@ static void bt3c_receive(bt3c_info_t *info)
if (info->rx_skb == NULL) { if (info->rx_skb == NULL) {
info->rx_state = RECV_WAIT_PACKET_TYPE; info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0; info->rx_count = 0;
if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!info->rx_skb) {
BT_ERR("Can't allocate mem for new packet"); BT_ERR("Can't allocate mem for new packet");
return; return;
} }
......
...@@ -149,7 +149,8 @@ static void btuart_write_wakeup(btuart_info_t *info) ...@@ -149,7 +149,8 @@ static void btuart_write_wakeup(btuart_info_t *info)
if (!pcmcia_dev_present(info->p_dev)) if (!pcmcia_dev_present(info->p_dev))
return; return;
if (!(skb = skb_dequeue(&(info->txq)))) skb = skb_dequeue(&(info->txq));
if (!skb)
break; break;
/* Send frame */ /* Send frame */
...@@ -190,7 +191,8 @@ static void btuart_receive(btuart_info_t *info) ...@@ -190,7 +191,8 @@ static void btuart_receive(btuart_info_t *info)
if (info->rx_skb == NULL) { if (info->rx_skb == NULL) {
info->rx_state = RECV_WAIT_PACKET_TYPE; info->rx_state = RECV_WAIT_PACKET_TYPE;
info->rx_count = 0; info->rx_count = 0;
if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!info->rx_skb) {
BT_ERR("Can't allocate mem for new packet"); BT_ERR("Can't allocate mem for new packet");
return; return;
} }
......
...@@ -159,6 +159,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -159,6 +159,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
......
...@@ -153,7 +153,8 @@ static void dtl1_write_wakeup(dtl1_info_t *info) ...@@ -153,7 +153,8 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
if (!pcmcia_dev_present(info->p_dev)) if (!pcmcia_dev_present(info->p_dev))
return; return;
if (!(skb = skb_dequeue(&(info->txq)))) skb = skb_dequeue(&(info->txq));
if (!skb)
break; break;
/* Send frame */ /* Send frame */
...@@ -215,13 +216,15 @@ static void dtl1_receive(dtl1_info_t *info) ...@@ -215,13 +216,15 @@ static void dtl1_receive(dtl1_info_t *info)
info->hdev->stat.byte_rx++; info->hdev->stat.byte_rx++;
/* Allocate packet */ /* Allocate packet */
if (info->rx_skb == NULL) if (info->rx_skb == NULL) {
if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) { info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
if (!info->rx_skb) {
BT_ERR("Can't allocate mem for new packet"); BT_ERR("Can't allocate mem for new packet");
info->rx_state = RECV_WAIT_NSH; info->rx_state = RECV_WAIT_NSH;
info->rx_count = NSHL; info->rx_count = NSHL;
return; return;
} }
}
*skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
nsh = (nsh_t *)info->rx_skb->data; nsh = (nsh_t *)info->rx_skb->data;
......
...@@ -291,7 +291,8 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) ...@@ -291,7 +291,8 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
/* First of all, check for unreliable messages in the queue, /* First of all, check for unreliable messages in the queue,
since they have priority */ since they have priority */
if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) { skb = skb_dequeue(&bcsp->unrel);
if (skb != NULL) {
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
if (nskb) { if (nskb) {
kfree_skb(skb); kfree_skb(skb);
...@@ -308,16 +309,20 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu) ...@@ -308,16 +309,20 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING); spin_lock_irqsave_nested(&bcsp->unack.lock, flags, SINGLE_DEPTH_NESTING);
if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) { if (bcsp->unack.qlen < BCSP_TXWINSIZE) {
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type); skb = skb_dequeue(&bcsp->rel);
if (nskb) { if (skb != NULL) {
__skb_queue_tail(&bcsp->unack, skb); struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len,
mod_timer(&bcsp->tbcsp, jiffies + HZ / 4); bt_cb(skb)->pkt_type);
spin_unlock_irqrestore(&bcsp->unack.lock, flags); if (nskb) {
return nskb; __skb_queue_tail(&bcsp->unack, skb);
} else { mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
skb_queue_head(&bcsp->rel, skb); spin_unlock_irqrestore(&bcsp->unack.lock, flags);
BT_ERR("Could not dequeue pkt because alloc_skb failed"); return nskb;
} else {
skb_queue_head(&bcsp->rel, skb);
BT_ERR("Could not dequeue pkt because alloc_skb failed");
}
} }
} }
...@@ -715,6 +720,9 @@ static int bcsp_open(struct hci_uart *hu) ...@@ -715,6 +720,9 @@ static int bcsp_open(struct hci_uart *hu)
static int bcsp_close(struct hci_uart *hu) static int bcsp_close(struct hci_uart *hu)
{ {
struct bcsp_struct *bcsp = hu->priv; struct bcsp_struct *bcsp = hu->priv;
del_timer_sync(&bcsp->tbcsp);
hu->priv = NULL; hu->priv = NULL;
BT_DBG("hu %p", hu); BT_DBG("hu %p", hu);
...@@ -722,7 +730,6 @@ static int bcsp_close(struct hci_uart *hu) ...@@ -722,7 +730,6 @@ static int bcsp_close(struct hci_uart *hu)
skb_queue_purge(&bcsp->unack); skb_queue_purge(&bcsp->unack);
skb_queue_purge(&bcsp->rel); skb_queue_purge(&bcsp->rel);
skb_queue_purge(&bcsp->unrel); skb_queue_purge(&bcsp->unrel);
del_timer(&bcsp->tbcsp);
kfree(bcsp); kfree(bcsp);
return 0; return 0;
......
...@@ -206,12 +206,12 @@ static int h5_close(struct hci_uart *hu) ...@@ -206,12 +206,12 @@ static int h5_close(struct hci_uart *hu)
{ {
struct h5 *h5 = hu->priv; struct h5 *h5 = hu->priv;
del_timer_sync(&h5->timer);
skb_queue_purge(&h5->unack); skb_queue_purge(&h5->unack);
skb_queue_purge(&h5->rel); skb_queue_purge(&h5->rel);
skb_queue_purge(&h5->unrel); skb_queue_purge(&h5->unrel);
del_timer(&h5->timer);
kfree(h5); kfree(h5);
return 0; return 0;
...@@ -673,7 +673,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu) ...@@ -673,7 +673,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu)
return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2); return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2);
} }
if ((skb = skb_dequeue(&h5->unrel)) != NULL) { skb = skb_dequeue(&h5->unrel);
if (skb != NULL) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len); skb->data, skb->len);
if (nskb) { if (nskb) {
...@@ -690,7 +691,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu) ...@@ -690,7 +691,8 @@ static struct sk_buff *h5_dequeue(struct hci_uart *hu)
if (h5->unack.qlen >= h5->tx_win) if (h5->unack.qlen >= h5->tx_win)
goto unlock; goto unlock;
if ((skb = skb_dequeue(&h5->rel)) != NULL) { skb = skb_dequeue(&h5->rel);
if (skb != NULL) {
nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type,
skb->data, skb->len); skb->data, skb->len);
if (nskb) { if (nskb) {
......
...@@ -271,7 +271,8 @@ static int hci_uart_tty_open(struct tty_struct *tty) ...@@ -271,7 +271,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if (tty->ops->write == NULL) if (tty->ops->write == NULL)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL);
if (!hu) {
BT_ERR("Can't allocate control structure"); BT_ERR("Can't allocate control structure");
return -ENFILE; return -ENFILE;
} }
...@@ -569,7 +570,8 @@ static int __init hci_uart_init(void) ...@@ -569,7 +570,8 @@ static int __init hci_uart_init(void)
hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup;
hci_uart_ldisc.owner = THIS_MODULE; hci_uart_ldisc.owner = THIS_MODULE;
if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { err = tty_register_ldisc(N_HCI, &hci_uart_ldisc);
if (err) {
BT_ERR("HCI line discipline registration failed. (%d)", err); BT_ERR("HCI line discipline registration failed. (%d)", err);
return err; return err;
} }
...@@ -614,7 +616,8 @@ static void __exit hci_uart_exit(void) ...@@ -614,7 +616,8 @@ static void __exit hci_uart_exit(void)
#endif #endif
/* Release tty registration of line discipline */ /* Release tty registration of line discipline */
if ((err = tty_unregister_ldisc(N_HCI))) err = tty_unregister_ldisc(N_HCI);
if (err)
BT_ERR("Can't unregister HCI line discipline (%d)", err); BT_ERR("Can't unregister HCI line discipline (%d)", err);
} }
......
...@@ -91,6 +91,13 @@ struct bt_uuid { ...@@ -91,6 +91,13 @@ struct bt_uuid {
u8 svc_hint; u8 svc_hint;
}; };
struct smp_csrk {
bdaddr_t bdaddr;
u8 bdaddr_type;
u8 master;
u8 val[16];
};
struct smp_ltk { struct smp_ltk {
struct list_head list; struct list_head list;
bdaddr_t bdaddr; bdaddr_t bdaddr;
...@@ -1263,8 +1270,10 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -1263,8 +1270,10 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
void mgmt_discovering(struct hci_dev *hdev, u8 discovering); void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_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_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key); void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
bool persistent);
void mgmt_reenable_advertising(struct hci_dev *hdev); void mgmt_reenable_advertising(struct hci_dev *hdev);
void mgmt_smp_complete(struct hci_conn *conn, bool complete); void mgmt_smp_complete(struct hci_conn *conn, bool complete);
......
...@@ -551,3 +551,15 @@ struct mgmt_ev_new_irk { ...@@ -551,3 +551,15 @@ struct mgmt_ev_new_irk {
bdaddr_t rpa; bdaddr_t rpa;
struct mgmt_irk_info irk; struct mgmt_irk_info irk;
} __packed; } __packed;
struct mgmt_csrk_info {
struct mgmt_addr_info addr;
__u8 master;
__u8 val[16];
} __packed;
#define MGMT_EV_NEW_CSRK 0x0019
struct mgmt_ev_new_csrk {
__u8 store_hint;
struct mgmt_csrk_info key;
} __packed;
...@@ -14,13 +14,34 @@ ...@@ -14,13 +14,34 @@
#ifndef __6LOWPAN_H #ifndef __6LOWPAN_H
#define __6LOWPAN_H #define __6LOWPAN_H
#include <linux/errno.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#if IS_ENABLED(CONFIG_BT_6LOWPAN)
int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb); int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
int bt_6lowpan_add_conn(struct l2cap_conn *conn); int bt_6lowpan_add_conn(struct l2cap_conn *conn);
int bt_6lowpan_del_conn(struct l2cap_conn *conn); int bt_6lowpan_del_conn(struct l2cap_conn *conn);
int bt_6lowpan_init(void); int bt_6lowpan_init(void);
void bt_6lowpan_cleanup(void); void bt_6lowpan_cleanup(void);
#else
static int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
return -EOPNOTSUPP;
}
static int bt_6lowpan_add_conn(struct l2cap_conn *conn)
{
return -EOPNOTSUPP;
}
int bt_6lowpan_del_conn(struct l2cap_conn *conn)
{
return -EOPNOTSUPP;
}
static int bt_6lowpan_init(void)
{
return -EOPNOTSUPP;
}
static void bt_6lowpan_cleanup(void) { }
#endif
#endif /* __6LOWPAN_H */ #endif /* __6LOWPAN_H */
...@@ -6,13 +6,13 @@ menuconfig BT ...@@ -6,13 +6,13 @@ menuconfig BT
tristate "Bluetooth subsystem support" tristate "Bluetooth subsystem support"
depends on NET && !S390 depends on NET && !S390
depends on RFKILL || !RFKILL depends on RFKILL || !RFKILL
select 6LOWPAN_IPHC if BT_6LOWPAN
select CRC16 select CRC16
select CRYPTO select CRYPTO
select CRYPTO_BLKCIPHER select CRYPTO_BLKCIPHER
select CRYPTO_AES select CRYPTO_AES
select CRYPTO_ECB select CRYPTO_ECB
select CRYPTO_SHA256 select CRYPTO_SHA256
select 6LOWPAN_IPHC
help help
Bluetooth is low-cost, low-power, short-range wireless technology. Bluetooth is low-cost, low-power, short-range wireless technology.
It was designed as a replacement for cables and other short-range It was designed as a replacement for cables and other short-range
...@@ -40,6 +40,12 @@ menuconfig BT ...@@ -40,6 +40,12 @@ menuconfig BT
to Bluetooth kernel modules are provided in the BlueZ packages. For to Bluetooth kernel modules are provided in the BlueZ packages. For
more information, see <http://www.bluez.org/>. more information, see <http://www.bluez.org/>.
config BT_6LOWPAN
bool "Bluetooth 6LoWPAN support"
depends on BT && IPV6
help
IPv6 compression over Bluetooth.
source "net/bluetooth/rfcomm/Kconfig" source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/bnep/Kconfig" source "net/bluetooth/bnep/Kconfig"
......
...@@ -10,6 +10,7 @@ obj-$(CONFIG_BT_HIDP) += hidp/ ...@@ -10,6 +10,7 @@ obj-$(CONFIG_BT_HIDP) += hidp/
bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
a2mp.o amp.o 6lowpan.o a2mp.o amp.o
bluetooth-$(CONFIG_BT_6LOWPAN) += 6lowpan.o
subdir-ccflags-y += -D__CHECK_ENDIAN__ subdir-ccflags-y += -D__CHECK_ENDIAN__
...@@ -162,7 +162,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -162,7 +162,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
return -ENOMEM; return -ENOMEM;
} }
rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); rsp->mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
rsp->ext_feat = 0; rsp->ext_feat = 0;
__a2mp_add_cl(mgr, rsp->cl); __a2mp_add_cl(mgr, rsp->cl);
...@@ -649,7 +649,7 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) ...@@ -649,7 +649,7 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
if (err) { if (err) {
struct a2mp_cmd_rej rej; struct a2mp_cmd_rej rej;
rej.reason = __constant_cpu_to_le16(0); rej.reason = cpu_to_le16(0);
hdr = (void *) skb->data; hdr = (void *) skb->data;
BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err);
...@@ -695,7 +695,13 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, ...@@ -695,7 +695,13 @@ static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state,
static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb) unsigned long len, int nb)
{ {
return bt_skb_alloc(len, GFP_KERNEL); struct sk_buff *skb;
skb = bt_skb_alloc(len, GFP_KERNEL);
if (!skb)
return ERR_PTR(-ENOMEM);
return skb;
} }
static struct l2cap_ops a2mp_chan_ops = { static struct l2cap_ops a2mp_chan_ops = {
......
...@@ -82,7 +82,7 @@ static void hci_acl_create_connection(struct hci_conn *conn) ...@@ -82,7 +82,7 @@ static void hci_acl_create_connection(struct hci_conn *conn)
cp.pscan_rep_mode = ie->data.pscan_rep_mode; cp.pscan_rep_mode = ie->data.pscan_rep_mode;
cp.pscan_mode = ie->data.pscan_mode; cp.pscan_mode = ie->data.pscan_mode;
cp.clock_offset = ie->data.clock_offset | cp.clock_offset = ie->data.clock_offset |
__constant_cpu_to_le16(0x8000); cpu_to_le16(0x8000);
} }
memcpy(conn->dev_class, ie->data.dev_class, 3); memcpy(conn->dev_class, ie->data.dev_class, 3);
...@@ -182,8 +182,8 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle) ...@@ -182,8 +182,8 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle)
cp.handle = cpu_to_le16(handle); cp.handle = cpu_to_le16(handle);
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.tx_bandwidth = cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40);
cp.voice_setting = cpu_to_le16(conn->setting); cp.voice_setting = cpu_to_le16(conn->setting);
switch (conn->setting & SCO_AIRMODE_MASK) { switch (conn->setting & SCO_AIRMODE_MASK) {
...@@ -225,8 +225,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, ...@@ -225,8 +225,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
cp.conn_interval_max = cpu_to_le16(max); cp.conn_interval_max = cpu_to_le16(max);
cp.conn_latency = cpu_to_le16(latency); cp.conn_latency = cpu_to_le16(latency);
cp.supervision_timeout = cpu_to_le16(to_multiplier); cp.supervision_timeout = cpu_to_le16(to_multiplier);
cp.min_ce_len = __constant_cpu_to_le16(0x0000); cp.min_ce_len = cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000); cp.max_ce_len = cpu_to_le16(0x0000);
hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
} }
...@@ -337,9 +337,9 @@ static void hci_conn_idle(struct work_struct *work) ...@@ -337,9 +337,9 @@ static void hci_conn_idle(struct work_struct *work)
if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) {
struct hci_cp_sniff_subrate cp; struct hci_cp_sniff_subrate cp;
cp.handle = cpu_to_le16(conn->handle); cp.handle = cpu_to_le16(conn->handle);
cp.max_latency = __constant_cpu_to_le16(0); cp.max_latency = cpu_to_le16(0);
cp.min_remote_timeout = __constant_cpu_to_le16(0); cp.min_remote_timeout = cpu_to_le16(0);
cp.min_local_timeout = __constant_cpu_to_le16(0); cp.min_local_timeout = cpu_to_le16(0);
hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
} }
...@@ -348,8 +348,8 @@ static void hci_conn_idle(struct work_struct *work) ...@@ -348,8 +348,8 @@ static void hci_conn_idle(struct work_struct *work)
cp.handle = cpu_to_le16(conn->handle); cp.handle = cpu_to_le16(conn->handle);
cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); cp.max_interval = cpu_to_le16(hdev->sniff_max_interval);
cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
cp.attempt = __constant_cpu_to_le16(4); cp.attempt = cpu_to_le16(4);
cp.timeout = __constant_cpu_to_le16(1); cp.timeout = cpu_to_le16(1);
hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
} }
} }
...@@ -596,9 +596,9 @@ static void hci_req_add_le_create_conn(struct hci_request *req, ...@@ -596,9 +596,9 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
cp.own_address_type = own_addr_type; cp.own_address_type = own_addr_type;
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval); cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval); cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a); cp.supervision_timeout = cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000); cp.min_ce_len = cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000); cp.max_ce_len = cpu_to_le16(0x0000);
hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
...@@ -781,6 +781,17 @@ int hci_conn_check_link_mode(struct hci_conn *conn) ...@@ -781,6 +781,17 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
{ {
BT_DBG("hcon %p", conn); BT_DBG("hcon %p", conn);
/* In Secure Connections Only mode, it is required that Secure
* Connections is used and the link is encrypted with AES-CCM
* using a P-256 authenticated combination key.
*/
if (test_bit(HCI_SC_ONLY, &conn->hdev->flags)) {
if (!hci_conn_sc_enabled(conn) ||
!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
conn->key_type != HCI_LK_AUTH_COMBINATION_P256)
return 0;
}
if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT))
return 0; return 0;
......
...@@ -1349,7 +1349,7 @@ static void bredr_setup(struct hci_request *req) ...@@ -1349,7 +1349,7 @@ static void bredr_setup(struct hci_request *req)
hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type); hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
/* Connection accept timeout ~20 secs */ /* Connection accept timeout ~20 secs */
param = __constant_cpu_to_le16(0x7d00); param = cpu_to_le16(0x7d00);
hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param); hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2, /* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
...@@ -5270,7 +5270,7 @@ void hci_req_add_le_passive_scan(struct hci_request *req) ...@@ -5270,7 +5270,7 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
memset(&enable_cp, 0, sizeof(enable_cp)); memset(&enable_cp, 0, sizeof(enable_cp));
enable_cp.enable = LE_SCAN_ENABLE; enable_cp.enable = LE_SCAN_ENABLE;
enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE; enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
&enable_cp); &enable_cp);
} }
...@@ -5313,10 +5313,6 @@ void hci_update_background_scan(struct hci_dev *hdev) ...@@ -5313,10 +5313,6 @@ void hci_update_background_scan(struct hci_dev *hdev)
* keep the background scan running. * keep the background scan running.
*/ */
/* If controller is already scanning we are done. */
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
return;
/* If controller is connecting, we should not start scanning /* If controller is connecting, we should not start scanning
* since some controllers are not able to scan and connect at * since some controllers are not able to scan and connect at
* the same time. * the same time.
...@@ -5325,6 +5321,12 @@ void hci_update_background_scan(struct hci_dev *hdev) ...@@ -5325,6 +5321,12 @@ void hci_update_background_scan(struct hci_dev *hdev)
if (conn) if (conn)
return; return;
/* If controller is currently scanning, we stop it to ensure we
* don't miss any advertising (due to duplicates filter).
*/
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
hci_req_add_le_scan_disable(&req);
hci_req_add_le_passive_scan(&req); hci_req_add_le_passive_scan(&req);
BT_DBG("%s starting background scanning", hdev->name); BT_DBG("%s starting background scanning", hdev->name);
......
...@@ -1924,9 +1924,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1924,9 +1924,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
bacpy(&cp.bdaddr, &ev->bdaddr); bacpy(&cp.bdaddr, &ev->bdaddr);
cp.pkt_type = cpu_to_le16(conn->pkt_type); cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.tx_bandwidth = cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40);
cp.max_latency = __constant_cpu_to_le16(0xffff); cp.max_latency = cpu_to_le16(0xffff);
cp.content_format = cpu_to_le16(hdev->voice_setting); cp.content_format = cpu_to_le16(hdev->voice_setting);
cp.retrans_effort = 0xff; cp.retrans_effort = 0xff;
...@@ -2183,6 +2183,18 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2183,6 +2183,18 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (!ev->status) if (!ev->status)
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
/* In Secure Connections Only mode, do not allow any
* connections that are not encrypted with AES-CCM
* using a P-256 authenticated combination key.
*/
if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
(!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_drop(conn);
goto unlock;
}
hci_proto_connect_cfm(conn, ev->status); hci_proto_connect_cfm(conn, ev->status);
hci_conn_drop(conn); hci_conn_drop(conn);
} else } else
...@@ -3157,6 +3169,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, ...@@ -3157,6 +3169,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
case 0x1c: /* SCO interval rejected */ case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */ case 0x1a: /* Unsupported Remote Feature */
case 0x1f: /* Unspecified error */ case 0x1f: /* Unspecified error */
case 0x20: /* Unsupported LMP Parameter value */
if (conn->out) { if (conn->out) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK); (hdev->esco_type & EDR_ESCO_MASK);
...@@ -3961,7 +3974,13 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3961,7 +3974,13 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
if (ltk->type & HCI_SMP_STK) { /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
* temporary key used to encrypt a connection following
* pairing. It is used during the Encrypted Session Setup to
* distribute the keys. Later, security can be re-established
* using a distributed LTK.
*/
if (ltk->type == HCI_SMP_STK_SLAVE) {
list_del(&ltk->list); list_del(&ltk->list);
kfree(ltk); kfree(ltk);
} }
......
...@@ -211,22 +211,22 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -211,22 +211,22 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT); opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
break; break;
case HCI_EVENT_PKT: case HCI_EVENT_PKT:
opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT); opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
break; break;
case HCI_ACLDATA_PKT: case HCI_ACLDATA_PKT:
if (bt_cb(skb)->incoming) if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT); opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
else else
opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT); opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
break; break;
case HCI_SCODATA_PKT: case HCI_SCODATA_PKT:
if (bt_cb(skb)->incoming) if (bt_cb(skb)->incoming)
opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT); opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
else else
opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT); opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
break; break;
default: default:
return; return;
...@@ -319,7 +319,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) ...@@ -319,7 +319,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
bacpy(&ni->bdaddr, &hdev->bdaddr); bacpy(&ni->bdaddr, &hdev->bdaddr);
memcpy(ni->name, hdev->name, 8); memcpy(ni->name, hdev->name, 8);
opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX); opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
break; break;
case HCI_DEV_UNREG: case HCI_DEV_UNREG:
...@@ -327,7 +327,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event) ...@@ -327,7 +327,7 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
if (!skb) if (!skb)
return NULL; return NULL;
opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX); opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
break; break;
default: default:
......
This diff is collapsed.
...@@ -111,7 +111,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) ...@@ -111,7 +111,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (bdaddr_type_is_le(la.l2_bdaddr_type)) { if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* We only allow ATT user space socket */ /* We only allow ATT user space socket */
if (la.l2_cid && if (la.l2_cid &&
la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL; return -EINVAL;
} }
...@@ -209,7 +209,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, ...@@ -209,7 +209,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
* ATT. Anything else is an invalid combination. * ATT. Anything else is an invalid combination.
*/ */
if (chan->scid != L2CAP_CID_ATT || if (chan->scid != L2CAP_CID_ATT ||
la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL; return -EINVAL;
/* We don't have the hdev available here to make a /* We don't have the hdev available here to make a
...@@ -227,7 +227,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, ...@@ -227,7 +227,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
if (bdaddr_type_is_le(la.l2_bdaddr_type)) { if (bdaddr_type_is_le(la.l2_bdaddr_type)) {
/* We only allow ATT user space socket */ /* We only allow ATT user space socket */
if (la.l2_cid && if (la.l2_cid &&
la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) la.l2_cid != cpu_to_le16(L2CAP_CID_ATT))
return -EINVAL; return -EINVAL;
} }
......
...@@ -108,6 +108,7 @@ static const u16 mgmt_events[] = { ...@@ -108,6 +108,7 @@ static const u16 mgmt_events[] = {
MGMT_EV_DEVICE_UNPAIRED, MGMT_EV_DEVICE_UNPAIRED,
MGMT_EV_PASSKEY_NOTIFY, MGMT_EV_PASSKEY_NOTIFY,
MGMT_EV_NEW_IRK, MGMT_EV_NEW_IRK,
MGMT_EV_NEW_CSRK,
}; };
#define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000)
...@@ -212,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) ...@@ -212,7 +213,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
hdr = (void *) skb_put(skb, sizeof(*hdr)); hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS); hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
hdr->index = cpu_to_le16(index); hdr->index = cpu_to_le16(index);
hdr->len = cpu_to_le16(sizeof(*ev)); hdr->len = cpu_to_le16(sizeof(*ev));
...@@ -243,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, ...@@ -243,7 +244,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
hdr = (void *) skb_put(skb, sizeof(*hdr)); hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE); hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
hdr->index = cpu_to_le16(index); hdr->index = cpu_to_le16(index);
hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
...@@ -269,7 +270,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -269,7 +270,7 @@ static int read_version(struct sock *sk, struct hci_dev *hdev, void *data,
BT_DBG("sock %p", sk); BT_DBG("sock %p", sk);
rp.version = MGMT_VERSION; rp.version = MGMT_VERSION;
rp.revision = __constant_cpu_to_le16(MGMT_REVISION); rp.revision = cpu_to_le16(MGMT_REVISION);
return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp, return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp,
sizeof(rp)); sizeof(rp));
...@@ -293,8 +294,8 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -293,8 +294,8 @@ static int read_commands(struct sock *sk, struct hci_dev *hdev, void *data,
if (!rp) if (!rp)
return -ENOMEM; return -ENOMEM;
rp->num_commands = __constant_cpu_to_le16(num_commands); rp->num_commands = cpu_to_le16(num_commands);
rp->num_events = __constant_cpu_to_le16(num_events); rp->num_events = cpu_to_le16(num_events);
for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++) for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++)
put_unaligned_le16(mgmt_commands[i], opcode); put_unaligned_le16(mgmt_commands[i], opcode);
...@@ -857,8 +858,8 @@ static void enable_advertising(struct hci_request *req) ...@@ -857,8 +858,8 @@ static void enable_advertising(struct hci_request *req)
return; return;
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
cp.min_interval = __constant_cpu_to_le16(0x0800); cp.min_interval = cpu_to_le16(0x0800);
cp.max_interval = __constant_cpu_to_le16(0x0800); cp.max_interval = cpu_to_le16(0x0800);
cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND; cp.type = connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND;
cp.own_address_type = own_addr_type; cp.own_address_type = own_addr_type;
cp.channel_map = hdev->le_adv_channel_map; cp.channel_map = hdev->le_adv_channel_map;
...@@ -1180,7 +1181,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, ...@@ -1180,7 +1181,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len,
if (hdev) if (hdev)
hdr->index = cpu_to_le16(hdev->id); hdr->index = cpu_to_le16(hdev->id);
else else
hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE); hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
hdr->len = cpu_to_le16(data_len); hdr->len = cpu_to_le16(data_len);
if (data) if (data)
...@@ -1492,15 +1493,15 @@ static void write_fast_connectable(struct hci_request *req, bool enable) ...@@ -1492,15 +1493,15 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
type = PAGE_SCAN_TYPE_INTERLACED; type = PAGE_SCAN_TYPE_INTERLACED;
/* 160 msec page scan interval */ /* 160 msec page scan interval */
acp.interval = __constant_cpu_to_le16(0x0100); acp.interval = cpu_to_le16(0x0100);
} else { } else {
type = PAGE_SCAN_TYPE_STANDARD; /* default */ type = PAGE_SCAN_TYPE_STANDARD; /* default */
/* default 1.28 sec page scan */ /* default 1.28 sec page scan */
acp.interval = __constant_cpu_to_le16(0x0800); acp.interval = cpu_to_le16(0x0800);
} }
acp.window = __constant_cpu_to_le16(0x0012); acp.window = cpu_to_le16(0x0012);
if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval || if (__cpu_to_le16(hdev->page_scan_interval) != acp.interval ||
__cpu_to_le16(hdev->page_scan_window) != acp.window) __cpu_to_le16(hdev->page_scan_window) != acp.window)
...@@ -2351,7 +2352,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -2351,7 +2352,7 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
sizeof(struct mgmt_link_key_info); sizeof(struct mgmt_link_key_info);
if (expected_len != len) { if (expected_len != len) {
BT_ERR("load_link_keys: expected %u bytes, got %u bytes", BT_ERR("load_link_keys: expected %u bytes, got %u bytes",
len, expected_len); expected_len, len);
return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
} }
...@@ -2761,11 +2762,23 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn) ...@@ -2761,11 +2762,23 @@ static struct pending_cmd *find_pairing(struct hci_conn *conn)
static void pairing_complete(struct pending_cmd *cmd, u8 status) static void pairing_complete(struct pending_cmd *cmd, u8 status)
{ {
const struct mgmt_cp_pair_device *cp = cmd->param;
struct mgmt_rp_pair_device rp; struct mgmt_rp_pair_device rp;
struct hci_conn *conn = cmd->user_data; struct hci_conn *conn = cmd->user_data;
bacpy(&rp.addr.bdaddr, &conn->dst); /* If we had a pairing failure we might have already received
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); * the remote Identity Address Information and updated the
* hci_conn variables with it, however we would not yet have
* notified user space of the resolved identity. Therefore, use
* the address given in the Pair Device command in case the
* pairing failed.
*/
if (status) {
memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
} else {
bacpy(&rp.addr.bdaddr, &conn->dst);
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
}
cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status, cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
&rp, sizeof(rp)); &rp, sizeof(rp));
...@@ -4427,7 +4440,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data, ...@@ -4427,7 +4440,7 @@ static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info); expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
if (expected_len != len) { if (expected_len != len) {
BT_ERR("load_irks: expected %u bytes, got %u bytes", BT_ERR("load_irks: expected %u bytes, got %u bytes",
len, expected_len); expected_len, len);
return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS, return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
} }
...@@ -4507,7 +4520,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, ...@@ -4507,7 +4520,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
sizeof(struct mgmt_ltk_info); sizeof(struct mgmt_ltk_info);
if (expected_len != len) { if (expected_len != len) {
BT_ERR("load_keys: expected %u bytes, got %u bytes", BT_ERR("load_keys: expected %u bytes, got %u bytes",
len, expected_len); expected_len, len);
return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
} }
...@@ -5004,7 +5017,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, ...@@ -5004,7 +5017,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
} }
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key) void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
{ {
struct mgmt_ev_new_long_term_key ev; struct mgmt_ev_new_long_term_key ev;
...@@ -5025,7 +5038,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key) ...@@ -5025,7 +5038,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
(key->bdaddr.b[5] & 0xc0) != 0xc0) (key->bdaddr.b[5] & 0xc0) != 0xc0)
ev.store_hint = 0x00; ev.store_hint = 0x00;
else else
ev.store_hint = 0x01; ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &key->bdaddr); bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
...@@ -5072,6 +5085,36 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk) ...@@ -5072,6 +5085,36 @@ void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL); mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
} }
void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
bool persistent)
{
struct mgmt_ev_new_csrk ev;
memset(&ev, 0, sizeof(ev));
/* Devices using resolvable or non-resolvable random addresses
* without providing an indentity resolving key don't require
* to store signature resolving keys. Their addresses will change
* the next time around.
*
* Only when a remote device provides an identity address
* make sure the signature resolving key is stored. So allow
* static random and public addresses here.
*/
if (csrk->bdaddr_type == ADDR_LE_DEV_RANDOM &&
(csrk->bdaddr.b[5] & 0xc0) != 0xc0)
ev.store_hint = 0x00;
else
ev.store_hint = persistent;
bacpy(&ev.key.addr.bdaddr, &csrk->bdaddr);
ev.key.addr.type = link_to_bdaddr(LE_LINK, csrk->bdaddr_type);
ev.key.master = csrk->master;
memcpy(ev.key.val, csrk->val, sizeof(csrk->val));
mgmt_event(MGMT_EV_NEW_CSRK, hdev, &ev, sizeof(ev), NULL);
}
static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
u8 data_len) u8 data_len)
{ {
...@@ -5665,9 +5708,9 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ...@@ -5665,9 +5708,9 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
ev->rssi = rssi; ev->rssi = rssi;
if (cfm_name) if (cfm_name)
ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME);
if (!ssp) if (!ssp)
ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING);
if (eir_len > 0) if (eir_len > 0)
memcpy(ev->eir, eir, eir_len); memcpy(ev->eir, eir, eir_len);
......
...@@ -768,7 +768,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, ...@@ -768,7 +768,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
bacpy(&addr.l2_bdaddr, dst); bacpy(&addr.l2_bdaddr, dst);
addr.l2_family = AF_BLUETOOTH; addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
addr.l2_cid = 0; addr.l2_cid = 0;
addr.l2_bdaddr_type = BDADDR_BREDR; addr.l2_bdaddr_type = BDADDR_BREDR;
*err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
...@@ -2032,7 +2032,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) ...@@ -2032,7 +2032,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
/* Bind socket */ /* Bind socket */
bacpy(&addr.l2_bdaddr, ba); bacpy(&addr.l2_bdaddr, ba);
addr.l2_family = AF_BLUETOOTH; addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
addr.l2_cid = 0; addr.l2_cid = 0;
addr.l2_bdaddr_type = BDADDR_BREDR; addr.l2_bdaddr_type = BDADDR_BREDR;
err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
......
...@@ -676,20 +676,20 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) ...@@ -676,20 +676,20 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
bacpy(&cp.bdaddr, &conn->dst); bacpy(&cp.bdaddr, &conn->dst);
cp.pkt_type = cpu_to_le16(conn->pkt_type); cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.tx_bandwidth = cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40);
cp.content_format = cpu_to_le16(setting); cp.content_format = cpu_to_le16(setting);
switch (setting & SCO_AIRMODE_MASK) { switch (setting & SCO_AIRMODE_MASK) {
case SCO_AIRMODE_TRANSP: case SCO_AIRMODE_TRANSP:
if (conn->pkt_type & ESCO_2EV3) if (conn->pkt_type & ESCO_2EV3)
cp.max_latency = __constant_cpu_to_le16(0x0008); cp.max_latency = cpu_to_le16(0x0008);
else else
cp.max_latency = __constant_cpu_to_le16(0x000D); cp.max_latency = cpu_to_le16(0x000D);
cp.retrans_effort = 0x02; cp.retrans_effort = 0x02;
break; break;
case SCO_AIRMODE_CVSD: case SCO_AIRMODE_CVSD:
cp.max_latency = __constant_cpu_to_le16(0xffff); cp.max_latency = cpu_to_le16(0xffff);
cp.retrans_effort = 0xff; cp.retrans_effort = 0xff;
break; break;
} }
......
This diff is collapsed.
...@@ -121,7 +121,7 @@ struct smp_cmd_security_req { ...@@ -121,7 +121,7 @@ struct smp_cmd_security_req {
#define SMP_FLAG_LTK_ENCRYPT 4 #define SMP_FLAG_LTK_ENCRYPT 4
#define SMP_FLAG_COMPLETE 5 #define SMP_FLAG_COMPLETE 5
#define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(250) #define SMP_REENCRYPT_TIMEOUT msecs_to_jiffies(500)
struct smp_chan { struct smp_chan {
struct l2cap_conn *conn; struct l2cap_conn *conn;
...@@ -136,6 +136,8 @@ struct smp_chan { ...@@ -136,6 +136,8 @@ struct smp_chan {
bdaddr_t id_addr; bdaddr_t id_addr;
u8 id_addr_type; u8 id_addr_type;
u8 irk[16]; u8 irk[16];
struct smp_csrk *csrk;
struct smp_csrk *slave_csrk;
struct smp_ltk *ltk; struct smp_ltk *ltk;
struct smp_ltk *slave_ltk; struct smp_ltk *slave_ltk;
struct smp_irk *remote_irk; struct smp_irk *remote_irk;
......
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