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

This commit is contained in:
John W. Linville 2013-10-18 13:56:17 -04:00
commit b231070a18
45 changed files with 1195 additions and 872 deletions

View file

@ -57,7 +57,7 @@ struct ath3k_version {
unsigned char reserved[0x07];
};
static struct usb_device_id ath3k_table[] = {
static const struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
{ USB_DEVICE(0x0CF3, 0x3000) },
@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
#define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files
* for AR3012 */
static struct usb_device_id ath3k_blist_tbl[] = {
static const struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },

View file

@ -42,7 +42,7 @@
static struct usb_driver bfusb_driver;
static struct usb_device_id bfusb_table[] = {
static const struct usb_device_id bfusb_table[] = {
/* AVM BlueFRITZ! USB */
{ USB_DEVICE(0x057c, 0x2200) },
@ -318,7 +318,6 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
return -ENOMEM;
}
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type;
data->reassembly = skb;
@ -333,7 +332,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
memcpy(skb_put(data->reassembly, len), buf, len);
if (hdr & 0x08) {
hci_recv_frame(data->reassembly);
hci_recv_frame(data->hdev, data->reassembly);
data->reassembly = NULL;
}
@ -465,26 +464,18 @@ static int bfusb_close(struct hci_dev *hdev)
return 0;
}
static int bfusb_send_frame(struct sk_buff *skb)
static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct bfusb_data *data;
struct bfusb_data *data = hci_get_drvdata(hdev);
struct sk_buff *nskb;
unsigned char buf[3];
int sent = 0, size, count;
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@ -544,11 +535,6 @@ static int bfusb_send_frame(struct sk_buff *skb)
return 0;
}
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
static int bfusb_load_firmware(struct bfusb_data *data,
const unsigned char *firmware, int count)
{
@ -699,11 +685,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
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->ioctl = bfusb_ioctl;
hdev->open = bfusb_open;
hdev->close = bfusb_close;
hdev->flush = bfusb_flush;
hdev->send = bfusb_send_frame;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");

View file

@ -399,7 +399,6 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = buf[i];
switch (bt_cb(info->rx_skb)->pkt_type) {
@ -477,7 +476,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
break;
case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb);
hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL;
break;
@ -659,17 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev)
}
static int bluecard_hci_send_frame(struct sk_buff *skb)
static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
bluecard_info_t *info;
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
bluecard_info_t *info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -693,12 +684,6 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
}
static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */
@ -734,11 +719,10 @@ static int bluecard_open(bluecard_info_t *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->ioctl = bluecard_hci_ioctl;
hdev->open = bluecard_hci_open;
hdev->close = bluecard_hci_close;
hdev->flush = bluecard_hci_flush;
hdev->send = bluecard_hci_send_frame;
id = inb(iobase + 0x30);

View file

@ -37,7 +37,7 @@
#define VERSION "0.10"
static struct usb_device_id bpa10x_table[] = {
static const struct usb_device_id bpa10x_table[] = {
/* Tektronix BPA 100/105 (Digianswer) */
{ USB_DEVICE(0x08fd, 0x0002) },
@ -129,8 +129,6 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
return -ENOMEM;
}
skb->dev = (void *) hdev;
data->rx_skb[queue] = skb;
scb = (void *) skb->cb;
@ -155,7 +153,7 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
data->rx_skb[queue] = NULL;
bt_cb(skb)->pkt_type = scb->type;
hci_recv_frame(skb);
hci_recv_frame(hdev, skb);
}
count -= len; buf += len;
@ -352,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev)
return 0;
}
static int bpa10x_send_frame(struct sk_buff *skb)
static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
@ -366,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
skb->dev = (void *) hdev;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;

View file

@ -247,7 +247,6 @@ static void bt3c_receive(bt3c_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
inb(iobase + DATA_H);
//printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
@ -318,7 +317,7 @@ static void bt3c_receive(bt3c_info_t *info)
break;
case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb);
hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL;
break;
@ -416,19 +415,11 @@ static int bt3c_hci_close(struct hci_dev *hdev)
}
static int bt3c_hci_send_frame(struct sk_buff *skb)
static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
bt3c_info_t *info;
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
bt3c_info_t *info = hci_get_drvdata(hdev);
unsigned long flags;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@ -455,12 +446,6 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
}
static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */
@ -577,11 +562,10 @@ static int bt3c_open(bt3c_info_t *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->ioctl = bt3c_hci_ioctl;
hdev->open = bt3c_hci_open;
hdev->close = bt3c_hci_close;
hdev->flush = bt3c_hci_flush;
hdev->send = bt3c_hci_send_frame;
/* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);

View file

@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
skb->dev = (void *) priv->btmrvl_dev.hcidev;
skb_queue_head(&priv->adapter->tx_queue, skb);
priv->btmrvl_dev.sendcmdflag = true;
@ -356,26 +355,12 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
priv->adapter = NULL;
}
static int btmrvl_ioctl(struct hci_dev *hdev,
unsigned int cmd, unsigned long arg)
static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
return -ENOIOCTLCMD;
}
static int btmrvl_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btmrvl_private *priv = NULL;
struct btmrvl_private *priv = hci_get_drvdata(hdev);
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
if (!hdev) {
BT_ERR("Frame for unknown HCI device");
return -ENODEV;
}
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,
@ -650,12 +635,11 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
priv->btmrvl_dev.hcidev = hdev;
hci_set_drvdata(hdev, priv);
hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open;
hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open;
hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame;
hdev->ioctl = btmrvl_ioctl;
hdev->send = btmrvl_send_frame;
hdev->setup = btmrvl_setup;
hdev->dev_type = priv->btmrvl_dev.dev_type;

View file

@ -600,15 +600,14 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case HCI_SCODATA_PKT:
case HCI_EVENT_PKT:
bt_cb(skb)->pkt_type = type;
skb->dev = (void *)hdev;
skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN);
if (type == HCI_EVENT_PKT) {
if (btmrvl_check_evtpkt(priv, skb))
hci_recv_frame(skb);
hci_recv_frame(hdev, skb);
} else {
hci_recv_frame(skb);
hci_recv_frame(hdev, skb);
}
hdev->stat.byte_rx += buf_len;
@ -616,12 +615,11 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case MRVL_VENDOR_PKT:
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
skb->dev = (void *)hdev;
skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN);
if (btmrvl_process_event(priv, skb))
hci_recv_frame(skb);
hci_recv_frame(hdev, skb);
hdev->stat.byte_rx += buf_len;
break;

View file

@ -157,10 +157,9 @@ static int btsdio_rx_packet(struct btsdio_data *data)
data->hdev->stat.byte_rx += len;
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = hdr[3];
err = hci_recv_frame(skb);
err = hci_recv_frame(data->hdev, skb);
if (err < 0)
return err;
@ -255,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev)
return 0;
}
static int btsdio_send_frame(struct sk_buff *skb)
static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);

View file

@ -198,7 +198,6 @@ static void btuart_receive(btuart_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
switch (bt_cb(info->rx_skb)->pkt_type) {
@ -265,7 +264,7 @@ static void btuart_receive(btuart_info_t *info)
break;
case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb);
hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL;
break;
@ -424,17 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev)
}
static int btuart_hci_send_frame(struct sk_buff *skb)
static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
btuart_info_t *info;
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
btuart_info_t *info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -458,12 +449,6 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
}
static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */
@ -495,11 +480,10 @@ static int btuart_open(btuart_info_t *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->ioctl = btuart_hci_ioctl;
hdev->open = btuart_hci_open;
hdev->close = btuart_hci_close;
hdev->flush = btuart_hci_flush;
hdev->send = btuart_hci_send_frame;
spin_lock_irqsave(&(info->lock), flags);

View file

@ -50,7 +50,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100
static struct usb_device_id btusb_table[] = {
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
@ -121,7 +121,7 @@ static struct usb_device_id btusb_table[] = {
MODULE_DEVICE_TABLE(usb, btusb_table);
static struct usb_device_id blacklist_table[] = {
static const struct usb_device_id blacklist_table[] = {
/* CSR BlueCore devices */
{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev)
return 0;
}
static int btusb_send_frame(struct sk_buff *skb)
static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
skb->dev = (void *) hdev;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
urb = usb_alloc_urb(0, GFP_ATOMIC);
@ -774,7 +775,7 @@ static int btusb_send_frame(struct sk_buff *skb)
break;
case HCI_SCODATA_PKT:
if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
return -ENODEV;
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
@ -833,8 +834,8 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG("%s evt %d", hdev->name, evt);
if (hdev->conn_hash.sco_num != data->sco_num) {
data->sco_num = hdev->conn_hash.sco_num;
if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
data->sco_num = hci_conn_num(hdev, SCO_LINK);
schedule_work(&data->work);
}
}
@ -889,7 +890,7 @@ static void btusb_work(struct work_struct *work)
int new_alts;
int err;
if (hdev->conn_hash.sco_num > 0) {
if (data->sco_num > 0) {
if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
if (err < 0) {
@ -903,9 +904,9 @@ static void btusb_work(struct work_struct *work)
if (hdev->voice_setting & 0x0020) {
static const int alts[3] = { 2, 4, 5 };
new_alts = alts[hdev->conn_hash.sco_num - 1];
new_alts = alts[data->sco_num - 1];
} else {
new_alts = hdev->conn_hash.sco_num;
new_alts = data->sco_num;
}
if (data->isoc_altsetting != new_alts) {

View file

@ -108,10 +108,8 @@ static long st_receive(void *priv_data, struct sk_buff *skb)
return -EFAULT;
}
skb->dev = (void *) lhst->hdev;
/* Forward skb to HCI core layer */
err = hci_recv_frame(skb);
err = hci_recv_frame(lhst->hdev, skb);
if (err < 0) {
BT_ERR("Unable to push skb to HCI core(%d)", err);
return err;
@ -253,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev)
return err;
}
static int ti_st_send_frame(struct sk_buff *skb)
static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev;
struct ti_st *hst;
long len;
hdev = (struct hci_dev *)skb->dev;
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;

View file

@ -256,9 +256,8 @@ static void dtl1_receive(dtl1_info_t *info)
case 0x83:
case 0x84:
/* send frame to the HCI layer */
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type &= 0x0f;
hci_recv_frame(info->rx_skb);
hci_recv_frame(info->hdev, info->rx_skb);
break;
default:
/* unknown packet */
@ -383,20 +382,12 @@ static int dtl1_hci_close(struct hci_dev *hdev)
}
static int dtl1_hci_send_frame(struct sk_buff *skb)
static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
dtl1_info_t *info;
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
dtl1_info_t *info = hci_get_drvdata(hdev);
struct sk_buff *s;
nsh_t nsh;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@ -438,12 +429,6 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
}
static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */
@ -477,11 +462,10 @@ static int dtl1_open(dtl1_info_t *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->ioctl = dtl1_hci_ioctl;
hdev->open = dtl1_hci_open;
hdev->close = dtl1_hci_close;
hdev->flush = dtl1_hci_flush;
hdev->send = dtl1_hci_send_frame;
spin_lock_irqsave(&(info->lock), flags);

View file

@ -522,7 +522,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
hci_recv_frame(bcsp->rx_skb);
hci_recv_frame(hu->hdev, bcsp->rx_skb);
} else {
BT_ERR ("Packet for unknown channel (%u %s)",
bcsp->rx_skb->data[1] & 0x0f,
@ -536,7 +536,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
/* Pull out BCSP hdr */
skb_pull(bcsp->rx_skb, 4);
hci_recv_frame(bcsp->rx_skb);
hci_recv_frame(hu->hdev, bcsp->rx_skb);
}
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
@ -655,7 +655,6 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
bcsp->rx_count = 0;
return 0;
}
bcsp->rx_skb->dev = (void *) hu->hdev;
break;
}
break;

View file

@ -124,30 +124,6 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0;
}
static inline int h4_check_data_len(struct h4_struct *h4, int len)
{
int room = skb_tailroom(h4->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
hci_recv_frame(h4->rx_skb);
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(h4->rx_skb);
} else {
h4->rx_state = H4_W4_DATA;
h4->rx_count = len;
return len;
}
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
return 0;
}
/* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count)
{

View file

@ -340,7 +340,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
/* Remove Three-wire header */
skb_pull(h5->rx_skb, 4);
hci_recv_frame(h5->rx_skb);
hci_recv_frame(hu->hdev, h5->rx_skb);
h5->rx_skb = NULL;
break;

View file

@ -234,21 +234,13 @@ static int hci_uart_close(struct hci_dev *hdev)
}
/* Send frames from HCI layer */
static int hci_uart_send_frame(struct sk_buff *skb)
static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev* hdev = (struct hci_dev *) skb->dev;
struct hci_uart *hu;
if (!hdev) {
BT_ERR("Frame for unknown device (hdev=NULL)");
return -ENODEV;
}
struct hci_uart *hu = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hu = hci_get_drvdata(hdev);
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
hu->proto->enqueue(hu, skb);

View file

@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
/* prepare packet */
hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
hcill_packet->cmd = cmd;
skb->dev = (void *) hu->hdev;
/* send packet */
skb_queue_tail(&ll->txq, skb);
@ -346,14 +345,14 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0;
}
static inline int ll_check_data_len(struct ll_struct *ll, int len)
static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len)
{
int room = skb_tailroom(ll->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
hci_recv_frame(ll->rx_skb);
hci_recv_frame(hdev, ll->rx_skb);
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(ll->rx_skb);
@ -395,7 +394,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
switch (ll->rx_state) {
case HCILL_W4_DATA:
BT_DBG("Complete data");
hci_recv_frame(ll->rx_skb);
hci_recv_frame(hu->hdev, ll->rx_skb);
ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_skb = NULL;
@ -406,7 +405,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
ll_check_data_len(ll, eh->plen);
ll_check_data_len(hu->hdev, ll, eh->plen);
continue;
case HCILL_W4_ACL_HDR:
@ -415,7 +414,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("ACL header: dlen %d", dlen);
ll_check_data_len(ll, dlen);
ll_check_data_len(hu->hdev, ll, dlen);
continue;
case HCILL_W4_SCO_HDR:
@ -423,7 +422,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("SCO header: dlen %d", sh->dlen);
ll_check_data_len(ll, sh->dlen);
ll_check_data_len(hu->hdev, ll, sh->dlen);
continue;
}
}
@ -494,7 +493,6 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
return -ENOMEM;
}
ll->rx_skb->dev = (void *) hu->hdev;
bt_cb(ll->rx_skb)->pkt_type = type;
}

View file

@ -81,21 +81,13 @@ static int vhci_flush(struct hci_dev *hdev)
return 0;
}
static int vhci_send_frame(struct sk_buff *skb)
static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev* hdev = (struct hci_dev *) skb->dev;
struct vhci_data *data;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
struct vhci_data *data = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hci_get_drvdata(hdev);
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb);
@ -179,10 +171,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
return -ENODEV;
}
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type;
ret = hci_recv_frame(skb);
ret = hci_recv_frame(data->hdev, skb);
break;
case HCI_VENDOR_PKT:

View file

@ -218,11 +218,10 @@ void baswap(bdaddr_t *dst, bdaddr_t *src);
struct bt_sock {
struct sock sk;
bdaddr_t src;
bdaddr_t dst;
struct list_head accept_q;
struct sock *parent;
unsigned long flags;
void (*skb_msg_name)(struct sk_buff *, void *, int *);
};
enum {
@ -285,6 +284,8 @@ struct bt_skb_cb {
__u8 force_active;
struct l2cap_ctrl control;
struct hci_req_ctrl req;
bdaddr_t bdaddr;
__le16 psm;
};
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))

View file

@ -64,16 +64,20 @@
#define HCI_AMP 0x01
/* First BR/EDR Controller shall have ID = 0 */
#define HCI_BREDR_ID 0
#define AMP_ID_BREDR 0x00
/* AMP controller types */
#define AMP_TYPE_BREDR 0x00
#define AMP_TYPE_80211 0x01
/* AMP controller status */
#define AMP_CTRL_POWERED_DOWN 0x00
#define AMP_CTRL_BLUETOOTH_ONLY 0x01
#define AMP_CTRL_NO_CAPACITY 0x02
#define AMP_CTRL_LOW_CAPACITY 0x03
#define AMP_CTRL_MEDIUM_CAPACITY 0x04
#define AMP_CTRL_HIGH_CAPACITY 0x05
#define AMP_CTRL_FULL_CAPACITY 0x06
#define AMP_STATUS_POWERED_DOWN 0x00
#define AMP_STATUS_BLUETOOTH_ONLY 0x01
#define AMP_STATUS_NO_CAPACITY 0x02
#define AMP_STATUS_LOW_CAPACITY 0x03
#define AMP_STATUS_MEDIUM_CAPACITY 0x04
#define AMP_STATUS_HIGH_CAPACITY 0x05
#define AMP_STATUS_FULL_CAPACITY 0x06
/* HCI device quirks */
enum {
@ -118,7 +122,7 @@ enum {
HCI_SSP_ENABLED,
HCI_HS_ENABLED,
HCI_LE_ENABLED,
HCI_LE_PERIPHERAL,
HCI_ADVERTISING,
HCI_CONNECTABLE,
HCI_DISCOVERABLE,
HCI_LINK_SECURITY,
@ -811,6 +815,14 @@ struct hci_cp_host_buffer_size {
__le16 sco_max_pkt;
} __packed;
#define HCI_OP_READ_NUM_SUPPORTED_IAC 0x0c38
struct hci_rp_read_num_supported_iac {
__u8 status;
__u8 num_iac;
} __packed;
#define HCI_OP_READ_CURRENT_IAC_LAP 0x0c39
#define HCI_OP_WRITE_INQUIRY_MODE 0x0c45
#define HCI_MAX_EIR_LENGTH 240
@ -847,6 +859,8 @@ struct hci_rp_read_inq_rsp_tx_power {
#define HCI_OP_SET_EVENT_MASK_PAGE_2 0x0c63
#define HCI_OP_READ_LOCATION_DATA 0x0c64
#define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66
struct hci_rp_read_flow_control_mode {
__u8 status;
@ -1042,6 +1056,23 @@ struct hci_rp_le_read_local_features {
#define HCI_OP_LE_SET_RANDOM_ADDR 0x2005
#define LE_ADV_IND 0x00
#define LE_ADV_DIRECT_IND 0x01
#define LE_ADV_SCAN_IND 0x02
#define LE_ADV_NONCONN_IND 0x03
#define HCI_OP_LE_SET_ADV_PARAM 0x2006
struct hci_cp_le_set_adv_param {
__le16 min_interval;
__le16 max_interval;
__u8 type;
__u8 own_address_type;
__u8 direct_addr_type;
bdaddr_t direct_addr;
__u8 channel_map;
__u8 filter_policy;
} __packed;
#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007
struct hci_rp_le_read_adv_tx_power {
__u8 status;

View file

@ -159,11 +159,14 @@ struct hci_dev {
__u16 manufacturer;
__u16 lmp_subver;
__u16 voice_setting;
__u8 num_iac;
__u8 io_capability;
__s8 inq_tx_power;
__u16 page_scan_interval;
__u16 page_scan_window;
__u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
__u16 devid_source;
__u16 devid_vendor;
@ -285,9 +288,8 @@ struct hci_dev {
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
int (*setup)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
};
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
@ -299,6 +301,8 @@ struct hci_conn {
bdaddr_t dst;
__u8 dst_type;
bdaddr_t src;
__u8 src_type;
__u16 handle;
__u16 state;
__u8 mode;
@ -704,19 +708,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
dev_set_drvdata(&hdev->dev, data);
}
/* hci_dev_list shall be locked */
static inline uint8_t __hci_num_ctrl(void)
{
uint8_t count = 0;
struct list_head *p;
list_for_each(p, &hci_dev_list) {
count++;
}
return count;
}
struct hci_dev *hci_dev_get(int index);
struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
@ -769,7 +760,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
@ -808,22 +799,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
/* returns true if at least one AMP active */
static inline bool hci_amp_capable(void)
{
struct hci_dev *hdev;
bool ret = false;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list)
if (hdev->amp_type == HCI_AMP &&
test_bit(HCI_UP, &hdev->flags))
ret = true;
read_unlock(&hci_dev_list_lock);
return ret;
}
/* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
@ -1121,24 +1096,24 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_BREDR_INQUIRY_LEN 0x08
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_index_added(struct hci_dev *hdev);
int mgmt_index_removed(struct hci_dev *hdev);
int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
void mgmt_index_added(struct hci_dev *hdev);
void mgmt_index_removed(struct hci_dev *hdev);
void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
int mgmt_powered(struct hci_dev *hdev, u8 powered);
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,
bool 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, u8 reason);
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);
void 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);
void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 reason);
void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status);
void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
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);
@ -1169,16 +1144,16 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
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);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len);
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_discovering(struct hci_dev *hdev, u8 discovering);
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len);
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
bool mgmt_valid_hdev(struct hci_dev *hdev);
int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
void mgmt_reenable_advertising(struct hci_dev *hdev);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
@ -1215,8 +1190,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
__u8 ltk[16]);
u8 bdaddr_to_le(u8 bdaddr_type);
#define SCO_AIRMODE_MASK 0x0003
#define SCO_AIRMODE_CVSD 0x0000
#define SCO_AIRMODE_TRANSP 0x0003

View file

@ -131,6 +131,7 @@ struct l2cap_conninfo {
/* L2CAP fixed channels */
#define L2CAP_FC_L2CAP 0x02
#define L2CAP_FC_CONNLESS 0x04
#define L2CAP_FC_A2MP 0x08
/* L2CAP Control Field bit masks */
@ -237,6 +238,7 @@ struct l2cap_conn_rsp {
/* protocol/service multiplexer (PSM) */
#define L2CAP_PSM_SDP 0x0001
#define L2CAP_PSM_RFCOMM 0x0003
#define L2CAP_PSM_3DSP 0x0021
/* channel indentifier */
#define L2CAP_CID_SIGNALING 0x0001
@ -442,7 +444,12 @@ struct l2cap_chan {
__u8 state;
bdaddr_t dst;
__u8 dst_type;
bdaddr_t src;
__u8 src_type;
__le16 psm;
__le16 sport;
__u16 dcid;
__u16 scid;
@ -453,8 +460,6 @@ struct l2cap_chan {
__u8 chan_type;
__u8 chan_policy;
__le16 sport;
__u8 sec_level;
__u8 ident;
@ -549,6 +554,7 @@ struct l2cap_ops {
int state);
void (*ready) (struct l2cap_chan *chan);
void (*defer) (struct l2cap_chan *chan);
void (*resume) (struct l2cap_chan *chan);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb);
};
@ -557,9 +563,6 @@ struct l2cap_conn {
struct hci_conn *hcon;
struct hci_chan *hchan;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu;
__u32 feat_mask;
@ -650,6 +653,7 @@ enum {
FLAG_FLUSHABLE,
FLAG_EXT_CTRL,
FLAG_EFS_ENABLE,
FLAG_DEFER_SETUP,
};
enum {

View file

@ -362,6 +362,13 @@ struct mgmt_cp_set_static_address {
} __packed;
#define MGMT_SET_STATIC_ADDRESS_SIZE 6
#define MGMT_OP_SET_SCAN_PARAMS 0x002C
struct mgmt_cp_set_scan_params {
__le16 interval;
__le16 window;
} __packed;
#define MGMT_SET_SCAN_PARAMS_SIZE 4
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;

View file

@ -300,6 +300,8 @@ struct rfcomm_conninfo {
struct rfcomm_pinfo {
struct bt_sock bt;
bdaddr_t src;
bdaddr_t dst;
struct rfcomm_dlc *dlc;
u8 channel;
u8 sec_level;

View file

@ -55,9 +55,6 @@ struct sco_conninfo {
struct sco_conn {
struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
spinlock_t lock;
struct sock *sk;
@ -72,6 +69,8 @@ struct sco_conn {
struct sco_pinfo {
struct bt_sock bt;
bdaddr_t src;
bdaddr_t dst;
__u32 flags;
__u16 setting;
struct sco_conn *conn;

View file

@ -15,8 +15,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
#include "a2mp.h"
#include "amp.h"
/* Global AMP Manager list */
LIST_HEAD(amp_mgr_list);
@ -75,33 +76,26 @@ u8 __next_ident(struct amp_mgr *mgr)
return mgr->ident;
}
static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
{
cl->id = 0;
cl->type = 0;
cl->status = 1;
}
/* hci_dev_list shall be locked */
static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
{
int i = 0;
struct hci_dev *hdev;
int i = 1;
__a2mp_cl_bredr(cl);
cl[0].id = AMP_ID_BREDR;
cl[0].type = AMP_TYPE_BREDR;
cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
list_for_each_entry(hdev, &hci_dev_list, list) {
/* Iterate through AMP controllers */
if (hdev->id == HCI_BREDR_ID)
continue;
/* Starting from second entry */
if (++i >= num_ctrl)
return;
cl[i].id = hdev->id;
cl[i].type = hdev->amp_type;
cl[i].status = hdev->amp_status;
if (hdev->dev_type == HCI_AMP) {
cl[i].id = hdev->id;
cl[i].type = hdev->amp_type;
if (test_bit(HCI_UP, &hdev->flags))
cl[i].status = hdev->amp_status;
else
cl[i].status = AMP_STATUS_POWERED_DOWN;
i++;
}
}
}
@ -129,6 +123,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
struct a2mp_discov_rsp *rsp;
u16 ext_feat;
u8 num_ctrl;
struct hci_dev *hdev;
if (len < sizeof(*req))
return -EINVAL;
@ -152,7 +147,14 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
read_lock(&hci_dev_list_lock);
num_ctrl = __hci_num_ctrl();
/* at minimum the BR/EDR needs to be listed */
num_ctrl = 1;
list_for_each_entry(hdev, &hci_dev_list, list) {
if (hdev->dev_type == HCI_AMP)
num_ctrl++;
}
len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp);
rsp = kmalloc(len, GFP_ATOMIC);
if (!rsp) {
@ -163,7 +165,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
rsp->ext_feat = 0;
__a2mp_add_cl(mgr, rsp->cl, num_ctrl);
__a2mp_add_cl(mgr, rsp->cl);
read_unlock(&hci_dev_list_lock);
@ -208,7 +210,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type,
cl->status);
if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) {
if (cl->id != AMP_ID_BREDR && cl->type != AMP_TYPE_BREDR) {
struct a2mp_info_req req;
found = true;
@ -344,7 +346,7 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb,
tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
hdev = hci_dev_get(req->id);
if (!hdev || hdev->amp_type == HCI_BREDR || tmp) {
if (!hdev || hdev->amp_type == AMP_TYPE_BREDR || tmp) {
struct a2mp_amp_assoc_rsp rsp;
rsp.id = req->id;
@ -451,7 +453,7 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
rsp.remote_id = req->local_id;
hdev = hci_dev_get(req->remote_id);
if (!hdev || hdev->amp_type != HCI_AMP) {
if (!hdev || hdev->amp_type == AMP_TYPE_BREDR) {
rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
goto send_rsp;
}
@ -535,7 +537,8 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
goto send_rsp;
}
hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, mgr->l2cap_conn->dst);
hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
&mgr->l2cap_conn->hcon->dst);
if (!hcon) {
BT_ERR("No phys link exist");
rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS;
@ -871,7 +874,7 @@ void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
rsp.id = hdev->id;
rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
if (hdev->amp_type != HCI_BREDR) {
if (hdev->amp_type != AMP_TYPE_BREDR) {
rsp.status = 0;
rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);

View file

@ -30,7 +30,7 @@
#include <net/bluetooth/bluetooth.h>
#include <linux/proc_fs.h>
#define VERSION "2.16"
#define VERSION "2.17"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
@ -221,12 +221,12 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
msg->msg_namelen = 0;
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) {
if (sk->sk_shutdown & RCV_SHUTDOWN)
if (sk->sk_shutdown & RCV_SHUTDOWN) {
msg->msg_namelen = 0;
return 0;
}
return err;
}
@ -238,9 +238,16 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err == 0)
if (err == 0) {
sock_recv_ts_and_drops(msg, sk, skb);
if (bt_sk(sk)->skb_msg_name)
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
&msg->msg_namelen);
else
msg->msg_namelen = 0;
}
skb_free_datagram(sk, skb);
return err ? : copied;
@ -604,7 +611,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
struct bt_sock_list *l = s->l;
if (v == SEQ_START_TOKEN) {
seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent");
seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
if (l->custom_seq_show) {
seq_putc(seq, ' ');
@ -617,15 +624,13 @@ static int bt_seq_show(struct seq_file *seq, void *v)
struct bt_sock *bt = bt_sk(sk);
seq_printf(seq,
"%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu",
"%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
sk,
atomic_read(&sk->sk_refcnt),
sk_rmem_alloc_get(sk),
sk_wmem_alloc_get(sk),
from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
sock_i_ino(sk),
&bt->src,
&bt->dst,
bt->parent? sock_i_ino(bt->parent): 0LU);
if (l->custom_seq_show) {

View file

@ -14,10 +14,11 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
#include <crypto/hash.h>
#include "a2mp.h"
#include "amp.h"
/* Remote AMP Controllers interface */
void amp_ctrl_get(struct amp_ctrl *ctrl)
{
@ -110,7 +111,7 @@ static u8 __next_handle(struct amp_mgr *mgr)
struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
u8 remote_id, bool out)
{
bdaddr_t *dst = mgr->l2cap_conn->dst;
bdaddr_t *dst = &mgr->l2cap_conn->hcon->dst;
struct hci_conn *hcon;
hcon = hci_conn_add(hdev, AMP_LINK, dst);
@ -409,7 +410,8 @@ void amp_create_logical_link(struct l2cap_chan *chan)
struct hci_cp_create_accept_logical_link cp;
struct hci_dev *hdev;
BT_DBG("chan %p hs_hcon %p dst %pMR", chan, hs_hcon, chan->conn->dst);
BT_DBG("chan %p hs_hcon %p dst %pMR", chan, hs_hcon,
&chan->conn->hcon->dst);
if (!hs_hcon)
return;

View file

@ -32,6 +32,7 @@
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/hci_core.h>
#include "bnep.h"
@ -510,20 +511,13 @@ static int bnep_session(void *arg)
static struct device *bnep_get_device(struct bnep_session *session)
{
bdaddr_t *src = &bt_sk(session->sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
struct hci_dev *hdev;
struct hci_conn *conn;
hdev = hci_get_route(dst, src);
if (!hdev)
conn = l2cap_pi(session->sock->sk)->chan->conn->hcon;
if (!conn)
return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
hci_dev_put(hdev);
return conn ? &conn->dev : NULL;
return &conn->dev;
}
static struct device_type bnep_type = {
@ -539,8 +533,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
BT_DBG("");
baswap((void *) dst, &bt_sk(sock->sk)->dst);
baswap((void *) src, &bt_sk(sock->sk)->src);
baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
/* session struct allocated as private part of net_device */
dev = alloc_netdev(sizeof(struct bnep_session),

View file

@ -340,20 +340,20 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
down_write(&cmtp_session_sem);
s = __cmtp_get_session(&bt_sk(sock->sk)->dst);
s = __cmtp_get_session(&l2cap_pi(sock->sk)->chan->dst);
if (s && s->state == BT_CONNECTED) {
err = -EEXIST;
goto failed;
}
bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst);
bacpy(&session->bdaddr, &l2cap_pi(sock->sk)->chan->dst);
session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
l2cap_pi(sock->sk)->chan->imtu);
BT_DBG("mtu %d", session->mtu);
sprintf(session->name, "%pMR", &bt_sk(sock->sk)->dst);
sprintf(session->name, "%pMR", &session->bdaddr);
session->sock = sock;
session->state = BT_CONFIG;

View file

@ -28,8 +28,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/smp.h>
#include "smp.h"
#include "a2mp.h"
struct sco_param {
u16 pkt_type;
@ -49,30 +50,6 @@ static const struct sco_param sco_param_wideband[] = {
{ EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */
};
static void hci_le_create_connection(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_create_conn cp;
conn->state = BT_CONNECT;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
memset(&cp, 0, sizeof(cp));
cp.scan_interval = __constant_cpu_to_le16(0x0060);
cp.scan_window = __constant_cpu_to_le16(0x0030);
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
}
static void hci_le_create_connection_cancel(struct hci_conn *conn)
{
hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
@ -404,6 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
return NULL;
bacpy(&conn->dst, dst);
bacpy(&conn->src, &hdev->bdaddr);
conn->hdev = hdev;
conn->type = type;
conn->mode = HCI_CM_ACTIVE;
@ -546,34 +524,128 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
EXPORT_SYMBOL(hci_get_route);
static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
{
struct hci_conn *conn;
if (status == 0)
return;
BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (!conn)
goto done;
conn->state = BT_CLOSED;
mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
status);
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
done:
hci_dev_unlock(hdev);
}
static int hci_create_le_conn(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_create_conn cp;
struct hci_request req;
int err;
hci_req_init(&req, hdev);
memset(&cp, 0, sizeof(cp));
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.own_address_type = conn->src_type;
cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
err = hci_req_run(&req, create_le_conn_complete);
if (err) {
hci_conn_del(conn);
return err;
}
return 0;
}
static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level, u8 auth_type)
{
struct hci_conn *le;
struct hci_conn *conn;
int err;
if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags))
if (test_bit(HCI_ADVERTISING, &hdev->flags))
return ERR_PTR(-ENOTSUPP);
le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
if (!le) {
le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (le)
return ERR_PTR(-EBUSY);
le = hci_conn_add(hdev, LE_LINK, dst);
if (!le)
return ERR_PTR(-ENOMEM);
le->dst_type = bdaddr_to_le(dst_type);
hci_le_create_connection(le);
/* Some devices send ATT messages as soon as the physical link is
* established. To be able to handle these ATT messages, the user-
* space first establishes the connection and then starts the pairing
* process.
*
* So if a hci_conn object already exists for the following connection
* attempt, we simply update pending_sec_level and auth_type fields
* and return the object found.
*/
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
if (conn) {
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
goto done;
}
le->pending_sec_level = sec_level;
le->auth_type = auth_type;
/* Since the controller supports only one LE connection attempt at a
* time, we return -EBUSY if there is any connection attempt running.
*/
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (conn)
return ERR_PTR(-EBUSY);
hci_conn_hold(le);
conn = hci_conn_add(hdev, LE_LINK, dst);
if (!conn)
return ERR_PTR(-ENOMEM);
return le;
if (dst_type == BDADDR_LE_PUBLIC)
conn->dst_type = ADDR_LE_DEV_PUBLIC;
else
conn->dst_type = ADDR_LE_DEV_RANDOM;
if (bacmp(&conn->src, BDADDR_ANY)) {
conn->src_type = ADDR_LE_DEV_PUBLIC;
} else {
bacpy(&conn->src, &hdev->static_addr);
conn->src_type = ADDR_LE_DEV_RANDOM;
}
conn->state = BT_CONNECT;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
err = hci_create_le_conn(conn);
if (err)
return ERR_PTR(err);
done:
hci_conn_hold(conn);
return conn;
}
static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,

View file

@ -307,11 +307,23 @@ static void amp_init(struct hci_request *req)
/* Read Local Version */
hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
/* Read Local Supported Commands */
hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
/* Read Local Supported Features */
hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
/* Read Local AMP Info */
hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
/* Read Data Blk size */
hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
/* Read Flow Control Mode */
hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
/* Read Location Data */
hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
}
static void hci_init1_req(struct hci_request *req, unsigned long opt)
@ -341,6 +353,8 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt)
static void bredr_setup(struct hci_request *req)
{
struct hci_dev *hdev = req->hdev;
__le16 param;
__u8 flt_type;
@ -356,6 +370,12 @@ static void bredr_setup(struct hci_request *req)
/* Read Voice Setting */
hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
/* Read Number of Supported IAC */
hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
/* Read Current IAC LAP */
hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
/* Clear Event Filters */
flt_type = HCI_FLT_CLEAR_ALL;
hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
@ -364,8 +384,10 @@ static void bredr_setup(struct hci_request *req)
param = __constant_cpu_to_le16(0x7d00);
hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
/* Read page scan parameters */
if (req->hdev->hci_ver > BLUETOOTH_VER_1_1) {
/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
* but it does not support page scan related HCI commands.
*/
if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
}
@ -1036,6 +1058,11 @@ int hci_inquiry(void __user *arg)
goto done;
}
if (hdev->dev_type != HCI_BREDR) {
err = -EOPNOTSUPP;
goto done;
}
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
@ -1105,7 +1132,7 @@ static u8 create_ad(struct hci_dev *hdev, u8 *ptr)
u8 ad_len = 0, flags = 0;
size_t name_len;
if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
flags |= LE_AD_GENERAL;
if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
@ -1196,13 +1223,29 @@ static int hci_dev_do_open(struct hci_dev *hdev)
goto done;
}
/* Check for rfkill but allow the HCI setup stage to proceed
* (which in itself doesn't cause any RF activity).
*/
if (test_bit(HCI_RFKILLED, &hdev->dev_flags) &&
!test_bit(HCI_SETUP, &hdev->dev_flags)) {
ret = -ERFKILL;
goto done;
if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
/* Check for rfkill but allow the HCI setup stage to
* proceed (which in itself doesn't cause any RF activity).
*/
if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
ret = -ERFKILL;
goto done;
}
/* Check for valid public address or a configured static
* random adddress, but let the HCI setup proceed to
* be able to determine if there is a public address
* or not.
*
* This check is only valid for BR/EDR controllers
* since AMP controllers do not have an address.
*/
if (hdev->dev_type == HCI_BREDR &&
!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!bacmp(&hdev->static_addr, BDADDR_ANY)) {
ret = -EADDRNOTAVAIL;
goto done;
}
}
if (test_bit(HCI_UP, &hdev->flags)) {
@ -1238,7 +1281,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
hci_notify(hdev, HCI_DEV_UP);
if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
mgmt_valid_hdev(hdev)) {
hdev->dev_type == HCI_BREDR) {
hci_dev_lock(hdev);
mgmt_powered(hdev, 1);
hci_dev_unlock(hdev);
@ -1288,6 +1331,10 @@ int hci_dev_open(__u16 dev)
if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
cancel_delayed_work(&hdev->power_off);
/* After this call it is guaranteed that the setup procedure
* has finished. This means that error conditions like RFKILL
* or no valid public or static random address apply.
*/
flush_workqueue(hdev->req_workqueue);
err = hci_dev_do_open(hdev);
@ -1341,6 +1388,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
if (!test_bit(HCI_RAW, &hdev->flags) &&
!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
@ -1373,15 +1421,16 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hdev->flags = 0;
hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
mgmt_valid_hdev(hdev)) {
hci_dev_lock(hdev);
mgmt_powered(hdev, 0);
hci_dev_unlock(hdev);
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
if (hdev->dev_type == HCI_BREDR) {
hci_dev_lock(hdev);
mgmt_powered(hdev, 0);
hci_dev_unlock(hdev);
}
}
/* Controller radio is available but is currently powered down */
hdev->amp_status = 0;
hdev->amp_status = AMP_STATUS_POWERED_DOWN;
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
@ -1500,6 +1549,11 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
goto done;
}
if (hdev->dev_type != HCI_BREDR) {
err = -EOPNOTSUPP;
goto done;
}
if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
@ -1703,7 +1757,14 @@ static void hci_power_on(struct work_struct *work)
return;
}
if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
/* During the HCI setup phase, a few error conditions are
* ignored and they need to be checked now. If they are still
* valid, it is important to turn the device back off.
*/
if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
(hdev->dev_type == HCI_BREDR &&
!bacmp(&hdev->bdaddr, BDADDR_ANY) &&
!bacmp(&hdev->static_addr, BDADDR_ANY))) {
clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
hci_dev_do_close(hdev);
} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
@ -2216,13 +2277,17 @@ struct hci_dev *hci_alloc_dev(void)
hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
hdev->esco_type = (ESCO_HV1);
hdev->link_mode = (HCI_LM_ACCEPT);
hdev->io_capability = 0x03; /* No Input No Output */
hdev->num_iac = 0x01; /* One IAC support is mandatory */
hdev->io_capability = 0x03; /* No Input No Output */
hdev->inq_tx_power = HCI_TX_POWER_INVALID;
hdev->adv_tx_power = HCI_TX_POWER_INVALID;
hdev->sniff_max_interval = 800;
hdev->sniff_min_interval = 80;
hdev->le_scan_interval = 0x0060;
hdev->le_scan_window = 0x0030;
mutex_init(&hdev->lock);
mutex_init(&hdev->req_lock);
@ -2329,9 +2394,9 @@ int hci_register_dev(struct hci_dev *hdev)
set_bit(HCI_RFKILLED, &hdev->dev_flags);
set_bit(HCI_SETUP, &hdev->dev_flags);
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
if (hdev->dev_type != HCI_AMP) {
set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
if (hdev->dev_type == HCI_BREDR) {
/* Assume BR/EDR support until proven otherwise (such as
* through reading supported features during init.
*/
@ -2435,9 +2500,8 @@ int hci_resume_dev(struct hci_dev *hdev)
EXPORT_SYMBOL(hci_resume_dev);
/* Receive frame from HCI drivers */
int hci_recv_frame(struct sk_buff *skb)
int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
&& !test_bit(HCI_INIT, &hdev->flags))) {
kfree_skb(skb);
@ -2496,7 +2560,6 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
scb->expect = hlen;
scb->pkt_type = type;
skb->dev = (void *) hdev;
hdev->reassembly[index] = skb;
}
@ -2556,7 +2619,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
/* Complete frame */
bt_cb(skb)->pkt_type = type;
hci_recv_frame(skb);
hci_recv_frame(hdev, skb);
hdev->reassembly[index] = NULL;
return remain;
@ -2647,15 +2710,8 @@ int hci_unregister_cb(struct hci_cb *cb)
}
EXPORT_SYMBOL(hci_unregister_cb);
static int hci_send_frame(struct sk_buff *skb)
static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev) {
kfree_skb(skb);
return -ENODEV;
}
BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
/* Time stamp */
@ -2672,7 +2728,8 @@ static int hci_send_frame(struct sk_buff *skb)
/* Get rid of skb owner, prior to sending to the driver. */
skb_orphan(skb);
return hdev->send(skb);
if (hdev->send(hdev, skb) < 0)
BT_ERR("%s sending frame failed", hdev->name);
}
void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
@ -2735,7 +2792,6 @@ static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
BT_DBG("skb len %d", skb->len);
bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
skb->dev = (void *) hdev;
return skb;
}
@ -2879,7 +2935,6 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
do {
skb = list; list = list->next;
skb->dev = (void *) hdev;
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
hci_add_acl_hdr(skb, conn->handle, flags);
@ -2898,8 +2953,6 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
skb->dev = (void *) hdev;
hci_queue_acl(chan, &chan->data_q, skb, flags);
queue_work(hdev->workqueue, &hdev->tx_work);
@ -2920,7 +2973,6 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
skb_reset_transport_header(skb);
memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
skb->dev = (void *) hdev;
bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
skb_queue_tail(&conn->data_q, skb);
@ -3185,7 +3237,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
hci_conn_enter_active_mode(chan->conn,
bt_cb(skb)->force_active);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
hdev->acl_last_tx = jiffies;
hdev->acl_cnt--;
@ -3237,7 +3289,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
hci_conn_enter_active_mode(chan->conn,
bt_cb(skb)->force_active);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
hdev->acl_last_tx = jiffies;
hdev->block_cnt -= blocks;
@ -3290,7 +3342,7 @@ static void hci_sched_sco(struct hci_dev *hdev)
while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
BT_DBG("skb %p len %d", skb, skb->len);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
conn->sent++;
if (conn->sent == ~0)
@ -3314,7 +3366,7 @@ static void hci_sched_esco(struct hci_dev *hdev)
&quote))) {
while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
BT_DBG("skb %p len %d", skb, skb->len);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
conn->sent++;
if (conn->sent == ~0)
@ -3356,7 +3408,7 @@ static void hci_sched_le(struct hci_dev *hdev)
skb = skb_dequeue(&chan->data_q);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
hdev->le_last_tx = jiffies;
cnt--;
@ -3392,7 +3444,7 @@ static void hci_tx_work(struct work_struct *work)
/* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
hci_send_frame(hdev, skb);
}
/* ----- HCI RX task (incoming data processing) ----- */
@ -3638,7 +3690,7 @@ static void hci_cmd_work(struct work_struct *work)
hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
if (hdev->sent_cmd) {
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(skb);
hci_send_frame(hdev, skb);
if (test_bit(HCI_RESET, &hdev->flags))
del_timer(&hdev->cmd_timer);
else
@ -3650,15 +3702,3 @@ static void hci_cmd_work(struct work_struct *work)
}
}
}
u8 bdaddr_to_le(u8 bdaddr_type)
{
switch (bdaddr_type) {
case BDADDR_LE_PUBLIC:
return ADDR_LE_DEV_PUBLIC;
default:
/* Fallback to LE Random address type */
return ADDR_LE_DEV_RANDOM;
}
}

View file

@ -29,8 +29,9 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
#include "a2mp.h"
#include "amp.h"
/* Handle HCI Event packets */
@ -417,6 +418,21 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
}
static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
hdev->num_iac = rp->num_iac;
BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
}
static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@ -918,12 +934,12 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
if (!status) {
if (*sent)
set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
set_bit(HCI_ADVERTISING, &hdev->dev_flags);
else
clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
}
if (!test_bit(HCI_INIT, &hdev->flags)) {
if (*sent && !test_bit(HCI_INIT, &hdev->flags)) {
struct hci_request req;
hci_req_init(&req, hdev);
@ -1005,7 +1021,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
} else {
hdev->features[1][0] &= ~LMP_HOST_LE;
clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
}
if (sent->simul)
@ -1296,9 +1312,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
goto unlock;
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);
struct hci_cp_auth_requested auth_cp;
auth_cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
sizeof(auth_cp), &auth_cp);
}
unlock:
@ -1470,33 +1488,6 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
hci_dev_unlock(hdev);
}
static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
{
struct hci_conn *conn;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status) {
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (!conn) {
hci_dev_unlock(hdev);
return;
}
BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
conn->state = BT_CLOSED;
mgmt_connect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status);
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
hci_dev_unlock(hdev);
}
}
static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
{
struct hci_cp_create_phy_link *cp;
@ -1826,10 +1817,25 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
if (ev->status == 0) {
if (conn->type == ACL_LINK && conn->flush_key)
u8 type = conn->type;
if (type == ACL_LINK && conn->flush_key)
hci_remove_link_key(hdev, &conn->dst);
hci_proto_disconn_cfm(conn, ev->reason);
hci_conn_del(conn);
/* Re-enable advertising if necessary, since it might
* have been disabled by the connection. From the
* HCI_LE_Set_Advertise_Enable command description in
* the core specification (v4.0):
* "The Controller shall continue advertising until the Host
* issues an LE_Set_Advertise_Enable command with
* Advertising_Enable set to 0x00 (Advertising is disabled)
* or until a connection is created or until the Advertising
* is timed out due to Directed Advertising."
*/
if (type == LE_LINK)
mgmt_reenable_advertising(hdev);
}
unlock:
@ -2144,6 +2150,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_write_voice_setting(hdev, skb);
break;
case HCI_OP_READ_NUM_SUPPORTED_IAC:
hci_cc_read_num_supported_iac(hdev, skb);
break;
case HCI_OP_WRITE_SSP_MODE:
hci_cc_write_ssp_mode(hdev, skb);
break;
@ -2347,10 +2357,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_disconnect(hdev, ev->status);
break;
case HCI_OP_LE_CREATE_CONN:
hci_cs_le_create_conn(hdev, ev->status);
break;
case HCI_OP_CREATE_PHY_LINK:
hci_cs_create_phylink(hdev, ev->status);
break;
@ -3490,6 +3496,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->dst_type = ev->bdaddr_type;
/* The advertising parameters for own address type
* define which source address and source address
* type this connections has.
*/
if (bacmp(&conn->src, BDADDR_ANY)) {
conn->src_type = ADDR_LE_DEV_PUBLIC;
} else {
bacpy(&conn->src, &hdev->static_addr);
conn->src_type = ADDR_LE_DEV_RANDOM;
}
if (ev->role == LE_CONN_ROLE_MASTER) {
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
@ -3645,8 +3662,8 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
skb_pull(skb, HCI_EVENT_HDR_SIZE);
if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
u16 opcode = __le16_to_cpu(hdr->opcode);
struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
hci_req_cmd_complete(hdev, opcode, 0);
}

View file

@ -387,7 +387,6 @@ static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
__net_timestamp(skb);
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}
@ -518,6 +517,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
return -EBUSY;
if (hdev->dev_type != HCI_BREDR)
return -EOPNOTSUPP;
switch (cmd) {
case HCISETRAW:
if (!capable(CAP_NET_ADMIN))
@ -550,10 +552,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
return hci_sock_blacklist_del(hdev, (void __user *) arg);
}
if (hdev->ioctl)
return hdev->ioctl(hdev, cmd, arg);
return -EINVAL;
return -ENOIOCTLCMD;
}
static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
@ -942,7 +941,6 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
skb_pull(skb, 1);
skb->dev = (void *) hdev;
if (hci_pi(sk)->channel == HCI_CHANNEL_RAW &&
bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {

View file

@ -767,10 +767,10 @@ static int hidp_setup_hid(struct hidp_session *session,
strncpy(hid->name, req->name, sizeof(req->name) - 1);
snprintf(hid->phys, sizeof(hid->phys), "%pMR",
&bt_sk(session->ctrl_sock->sk)->src);
&l2cap_pi(session->ctrl_sock->sk)->chan->src);
snprintf(hid->uniq, sizeof(hid->uniq), "%pMR",
&bt_sk(session->ctrl_sock->sk)->dst);
&l2cap_pi(session->ctrl_sock->sk)->chan->dst);
hid->dev.parent = &session->conn->hcon->dev;
hid->ll_driver = &hidp_hid_driver;
@ -1283,23 +1283,29 @@ static int hidp_session_thread(void *arg)
static int hidp_verify_sockets(struct socket *ctrl_sock,
struct socket *intr_sock)
{
struct l2cap_chan *ctrl_chan, *intr_chan;
struct bt_sock *ctrl, *intr;
struct hidp_session *session;
if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock))
return -EINVAL;
ctrl_chan = l2cap_pi(ctrl_sock->sk)->chan;
intr_chan = l2cap_pi(intr_sock->sk)->chan;
if (bacmp(&ctrl_chan->src, &intr_chan->src) ||
bacmp(&ctrl_chan->dst, &intr_chan->dst))
return -ENOTUNIQ;
ctrl = bt_sk(ctrl_sock->sk);
intr = bt_sk(intr_sock->sk);
if (bacmp(&ctrl->src, &intr->src) || bacmp(&ctrl->dst, &intr->dst))
return -ENOTUNIQ;
if (ctrl->sk.sk_state != BT_CONNECTED ||
intr->sk.sk_state != BT_CONNECTED)
return -EBADFD;
/* early session check, we check again during session registration */
session = hidp_session_find(&ctrl->dst);
session = hidp_session_find(&ctrl_chan->dst);
if (session) {
hidp_session_put(session);
return -EEXIST;
@ -1332,7 +1338,7 @@ int hidp_connection_add(struct hidp_connadd_req *req,
if (!conn)
return -EBADFD;
ret = hidp_session_new(&session, &bt_sk(ctrl_sock->sk)->dst, ctrl_sock,
ret = hidp_session_new(&session, &chan->dst, ctrl_sock,
intr_sock, req, conn);
if (ret)
goto out_conn;

View file

@ -36,14 +36,15 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
#include "smp.h"
#include "a2mp.h"
#include "amp.h"
bool disable_ertm;
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, };
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP | L2CAP_FC_CONNLESS, };
static LIST_HEAD(chan_list);
static DEFINE_RWLOCK(chan_list_lock);
@ -58,6 +59,18 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
struct sk_buff_head *skbs, u8 event);
static inline __u8 bdaddr_type(struct hci_conn *hcon, __u8 type)
{
if (hcon->type == LE_LINK) {
if (type == ADDR_LE_DEV_PUBLIC)
return BDADDR_LE_PUBLIC;
else
return BDADDR_LE_RANDOM;
}
return BDADDR_BREDR;
}
/* ---- L2CAP channels ---- */
static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
@ -148,7 +161,7 @@ static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
struct l2cap_chan *c;
list_for_each_entry(c, &chan_list, global_l) {
if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
if (c->sport == psm && !bacmp(&c->src, src))
return c;
}
return NULL;
@ -620,10 +633,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
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 %s sk %p", chan, state_to_string(chan->state),
sk);
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
switch (chan->state) {
case BT_LISTEN:
@ -634,6 +645,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
case BT_CONFIG:
if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
conn->hcon->type == ACL_LINK) {
struct sock *sk = chan->sk;
__set_chan_timer(chan, sk->sk_sndtimeo);
l2cap_send_disconn_req(chan, reason);
} else
@ -646,10 +658,11 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
struct l2cap_conn_rsp rsp;
__u16 result;
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
result = L2CAP_CR_SEC_BLOCK;
else
result = L2CAP_CR_BAD_PSM;
l2cap_state_change(chan, BT_DISCONN);
rsp.scid = cpu_to_le16(chan->dcid);
@ -676,7 +689,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{
if (chan->chan_type == L2CAP_CHAN_RAW) {
switch (chan->chan_type) {
case L2CAP_CHAN_RAW:
switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_DEDICATED_BONDING_MITM;
@ -685,15 +699,29 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
default:
return HCI_AT_NO_BONDING;
}
} else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
if (chan->sec_level == BT_SECURITY_LOW)
chan->sec_level = BT_SECURITY_SDP;
break;
case L2CAP_CHAN_CONN_LESS:
if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_3DSP)) {
if (chan->sec_level == BT_SECURITY_LOW)
chan->sec_level = BT_SECURITY_SDP;
}
if (chan->sec_level == BT_SECURITY_HIGH)
return HCI_AT_NO_BONDING_MITM;
else
return HCI_AT_NO_BONDING;
} else {
break;
case L2CAP_CHAN_CONN_ORIENTED:
if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) {
if (chan->sec_level == BT_SECURITY_LOW)
chan->sec_level = BT_SECURITY_SDP;
if (chan->sec_level == BT_SECURITY_HIGH)
return HCI_AT_NO_BONDING_MITM;
else
return HCI_AT_NO_BONDING;
}
/* fall through */
default:
switch (chan->sec_level) {
case BT_SECURITY_HIGH:
return HCI_AT_GENERAL_BONDING_MITM;
@ -702,6 +730,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
default:
return HCI_AT_NO_BONDING;
}
break;
}
}
@ -1015,11 +1044,27 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
static bool __amp_capable(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = chan->conn;
struct hci_dev *hdev;
bool amp_available = false;
if (conn->hs_enabled && hci_amp_capable() &&
chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
conn->fixed_chan_mask & L2CAP_FC_A2MP)
return true;
if (!conn->hs_enabled)
return false;
if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
return false;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list) {
if (hdev->amp_type != AMP_TYPE_BREDR &&
test_bit(HCI_UP, &hdev->flags)) {
amp_available = true;
break;
}
}
read_unlock(&hci_dev_list_lock);
if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
return amp_available;
return false;
}
@ -1224,8 +1269,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
mutex_lock(&conn->chan_lock);
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
struct sock *sk = chan->sk;
l2cap_chan_lock(chan);
if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
@ -1257,9 +1300,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp.dcid = cpu_to_le16(chan->scid);
if (l2cap_chan_check_security(chan)) {
struct sock *sk = chan->sk;
lock_sock(sk);
if (test_bit(BT_SK_DEFER_SETUP,
&bt_sk(sk)->flags)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
chan->ops->defer(chan);
@ -1308,8 +1352,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
if (state && c->state != state)
continue;
@ -1318,16 +1360,16 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
int src_any, dst_any;
/* Exact match. */
src_match = !bacmp(&bt_sk(sk)->src, src);
dst_match = !bacmp(&bt_sk(sk)->dst, dst);
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
read_unlock(&chan_list_lock);
return c;
}
/* Closest match */
src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
src_any = !bacmp(&c->src, BDADDR_ANY);
dst_any = !bacmp(&c->dst, BDADDR_ANY);
if ((src_match && dst_any) || (src_any && dst_match) ||
(src_any && dst_any))
c1 = c;
@ -1348,7 +1390,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
/* Check if we have socket listening on cid */
pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT,
conn->src, conn->dst);
&conn->hcon->src, &conn->hcon->dst);
if (!pchan)
return;
@ -1366,8 +1408,10 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
chan->dcid = L2CAP_CID_ATT;
bacpy(&bt_sk(chan->sk)->src, conn->src);
bacpy(&bt_sk(chan->sk)->dst, conn->dst);
bacpy(&chan->src, &conn->hcon->src);
bacpy(&chan->dst, &conn->hcon->dst);
chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
__l2cap_chan_add(conn, chan);
@ -1632,9 +1676,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
break;
}
conn->src = &hcon->hdev->bdaddr;
conn->dst = &hcon->dst;
conn->feat_mask = 0;
if (hcon->type == ACL_LINK)
@ -1691,8 +1732,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
if (state && c->state != state)
continue;
@ -1701,16 +1740,16 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
int src_any, dst_any;
/* Exact match. */
src_match = !bacmp(&bt_sk(sk)->src, src);
dst_match = !bacmp(&bt_sk(sk)->dst, dst);
src_match = !bacmp(&c->src, src);
dst_match = !bacmp(&c->dst, dst);
if (src_match && dst_match) {
read_unlock(&chan_list_lock);
return c;
}
/* Closest match */
src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
src_any = !bacmp(&c->src, BDADDR_ANY);
dst_any = !bacmp(&c->dst, BDADDR_ANY);
if ((src_match && dst_any) || (src_any && dst_match) ||
(src_any && dst_any))
c1 = c;
@ -1726,17 +1765,16 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type)
{
struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src;
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
__u8 auth_type;
int err;
BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
dst_type, __le16_to_cpu(psm));
hdev = hci_get_route(dst, src);
hdev = hci_get_route(dst, &chan->src);
if (!hdev)
return -EHOSTUNREACH;
@ -1793,9 +1831,8 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
}
/* Set destination address and psm */
lock_sock(sk);
bacpy(&bt_sk(sk)->dst, dst);
release_sock(sk);
bacpy(&chan->dst, dst);
chan->dst_type = dst_type;
chan->psm = psm;
chan->dcid = cid;
@ -1828,7 +1865,8 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
}
/* Update source addr of the socket */
bacpy(src, conn->src);
bacpy(&chan->src, &hcon->src);
chan->src_type = bdaddr_type(hcon, hcon->src_type);
l2cap_chan_unlock(chan);
l2cap_chan_add(conn, chan);
@ -2266,7 +2304,8 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
struct l2cap_hdr *lh;
BT_DBG("chan %p len %zu priority %u", chan, len, priority);
BT_DBG("chan %p psm 0x%2.2x len %zu priority %u", chan,
__le16_to_cpu(chan->psm), len, priority);
count = min_t(unsigned int, (conn->mtu - hlen), len);
@ -2281,7 +2320,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(chan->dcid);
lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
if (unlikely(err < 0)) {
@ -3046,8 +3085,8 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
skb_queue_head_init(&chan->tx_q);
chan->local_amp_id = 0;
chan->move_id = 0;
chan->local_amp_id = AMP_ID_BREDR;
chan->move_id = AMP_ID_BREDR;
chan->move_state = L2CAP_MOVE_STABLE;
chan->move_role = L2CAP_MOVE_ROLE_NONE;
@ -3100,7 +3139,7 @@ static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
struct l2cap_conf_rfc *rfc)
{
if (chan->local_amp_id && chan->hs_hcon) {
if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
/* Class 1 devices have must have ERTM timeouts
@ -3727,7 +3766,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
/* Check if we have socket listening on psm */
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
&conn->hcon->dst);
if (!pchan) {
result = L2CAP_CR_BAD_PSM;
goto sendresp;
@ -3765,8 +3805,10 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
*/
conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
bacpy(&chan->src, &conn->hcon->src);
bacpy(&chan->dst, &conn->hcon->dst);
chan->src_type = bdaddr_type(conn->hcon, conn->hcon->src_type);
chan->dst_type = bdaddr_type(conn->hcon, conn->hcon->dst_type);
chan->psm = psm;
chan->dcid = scid;
chan->local_amp_id = amp_id;
@ -3781,7 +3823,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
if (l2cap_chan_check_security(chan)) {
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
status = L2CAP_CS_AUTHOR_PEND;
@ -3791,12 +3833,12 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
* The connection will succeed after the
* physical link is up.
*/
if (amp_id) {
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
} else {
if (amp_id == AMP_ID_BREDR) {
__l2cap_state_change(chan, BT_CONFIG);
result = L2CAP_CR_SUCCESS;
} else {
__l2cap_state_change(chan, BT_CONNECT2);
result = L2CAP_CR_PEND;
}
status = L2CAP_CS_NO_INFO;
}
@ -4423,7 +4465,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
/* For controller id 0 make BR/EDR connection */
if (req->amp_id == HCI_BREDR_ID) {
if (req->amp_id == AMP_ID_BREDR) {
l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
req->amp_id);
return 0;
@ -4445,7 +4487,8 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
struct amp_mgr *mgr = conn->hcon->amp_mgr;
struct hci_conn *hs_hcon;
hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst);
hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
&conn->hcon->dst);
if (!hs_hcon) {
hci_dev_put(hdev);
return -EBADSLT;
@ -4658,7 +4701,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
if (chan->state != BT_CONNECTED) {
/* Ignore logical link if channel is on BR/EDR */
if (chan->local_amp_id)
if (chan->local_amp_id != AMP_ID_BREDR)
l2cap_logical_finish_create(chan, hchan);
} else {
l2cap_logical_finish_move(chan, hchan);
@ -4669,7 +4712,7 @@ void l2cap_move_start(struct l2cap_chan *chan)
{
BT_DBG("chan %p", chan);
if (chan->local_amp_id == HCI_BREDR_ID) {
if (chan->local_amp_id == AMP_ID_BREDR) {
if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
return;
chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
@ -4868,7 +4911,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
goto send_move_response;
}
if (req->dest_amp_id) {
if (req->dest_amp_id != AMP_ID_BREDR) {
struct hci_dev *hdev;
hdev = hci_dev_get(req->dest_amp_id);
if (!hdev || hdev->dev_type != HCI_AMP ||
@ -4888,7 +4931,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
*/
if ((__chan_is_moving(chan) ||
chan->move_role != L2CAP_MOVE_ROLE_NONE) &&
bacmp(conn->src, conn->dst) > 0) {
bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) {
result = L2CAP_MR_COLLISION;
goto send_move_response;
}
@ -4898,7 +4941,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
chan->move_id = req->dest_amp_id;
icid = chan->dcid;
if (!req->dest_amp_id) {
if (req->dest_amp_id == AMP_ID_BREDR) {
/* Moving to BR/EDR */
if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
@ -5090,7 +5133,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
if (result == L2CAP_MC_CONFIRMED) {
chan->local_amp_id = chan->move_id;
if (!chan->local_amp_id)
if (chan->local_amp_id == AMP_ID_BREDR)
__release_logical_link(chan);
} else {
chan->move_id = chan->local_amp_id;
@ -5130,7 +5173,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
chan->local_amp_id = chan->move_id;
if (!chan->local_amp_id && chan->hs_hchan)
if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
__release_logical_link(chan);
l2cap_move_done(chan);
@ -6403,7 +6446,8 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
if (hcon->type != ACL_LINK)
goto drop;
chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
chan = l2cap_global_chan_by_psm(0, psm, &conn->hcon->src,
&conn->hcon->dst);
if (!chan)
goto drop;
@ -6415,6 +6459,10 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
if (chan->imtu < skb->len)
goto drop;
/* Store remote BD_ADDR and PSM for msg_name */
bacpy(&bt_cb(skb)->bdaddr, &conn->hcon->dst);
bt_cb(skb)->psm = psm;
if (!chan->ops->recv(chan, skb))
return;
@ -6432,7 +6480,7 @@ static void l2cap_att_channel(struct l2cap_conn *conn,
goto drop;
chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT,
conn->src, conn->dst);
&conn->hcon->src, &conn->hcon->dst);
if (!chan)
goto drop;
@ -6507,17 +6555,15 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
/* Find listening sockets and check their link_mode */
read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
if (c->state != BT_LISTEN)
continue;
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
if (!bacmp(&c->src, &hdev->bdaddr)) {
lm1 |= HCI_LM_ACCEPT;
if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
lm1 |= HCI_LM_MASTER;
exact++;
} else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
} else if (!bacmp(&c->src, BDADDR_ANY)) {
lm2 |= HCI_LM_ACCEPT;
if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
lm2 |= HCI_LM_MASTER;
@ -6623,11 +6669,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (!status && (chan->state == BT_CONNECTED ||
chan->state == BT_CONFIG)) {
struct sock *sk = chan->sk;
clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
sk->sk_state_change(sk);
chan->ops->resume(chan);
l2cap_check_encryption(chan, encrypt);
l2cap_chan_unlock(chan);
continue;
@ -6647,8 +6689,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
lock_sock(sk);
if (!status) {
if (test_bit(BT_SK_DEFER_SETUP,
&bt_sk(sk)->flags)) {
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
res = L2CAP_CR_PEND;
stat = L2CAP_CS_AUTHOR_PEND;
chan->ops->defer(chan);
@ -6782,9 +6823,13 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
conn->rx_len -= skb->len;
if (!conn->rx_len) {
/* Complete frame received */
l2cap_recv_frame(conn, conn->rx_skb);
/* Complete frame received. l2cap_recv_frame
* takes ownership of the skb so set the global
* rx_skb pointer to NULL first.
*/
struct sk_buff *rx_skb = conn->rx_skb;
conn->rx_skb = NULL;
l2cap_recv_frame(conn, rx_skb);
}
break;
}
@ -6801,10 +6846,8 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
read_lock(&chan_list_lock);
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
&bt_sk(sk)->src, &bt_sk(sk)->dst,
&c->src, &c->dst,
c->state, __le16_to_cpu(c->psm),
c->scid, c->dcid, c->imtu, c->omtu,
c->sec_level, c->mode);

View file

@ -32,7 +32,8 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
#include "smp.h"
static struct bt_sock_list l2cap_sk_list = {
.lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
@ -68,6 +69,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (la.l2_cid && la.l2_psm)
return -EINVAL;
if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL;
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
@ -99,11 +103,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (err < 0)
goto done;
if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP ||
__le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
chan->sec_level = BT_SECURITY_SDP;
switch (chan->chan_type) {
case L2CAP_CHAN_CONN_LESS:
if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_3DSP)
chan->sec_level = BT_SECURITY_SDP;
break;
case L2CAP_CHAN_CONN_ORIENTED:
if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP ||
__le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
chan->sec_level = BT_SECURITY_SDP;
break;
}
bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
bacpy(&chan->src, &la.l2_bdaddr);
chan->src_type = la.l2_bdaddr_type;
chan->state = BT_BOUND;
sk->sk_state = BT_BOUND;
@ -134,6 +147,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
if (la.l2_cid && la.l2_psm)
return -EINVAL;
if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL;
if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR)
return -EINVAL;
if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR)
return -EINVAL;
err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
&la.l2_bdaddr, la.l2_bdaddr_type);
if (err)
@ -265,12 +287,14 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
if (peer) {
la->l2_psm = chan->psm;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
bacpy(&la->l2_bdaddr, &chan->dst);
la->l2_cid = cpu_to_le16(chan->dcid);
la->l2_bdaddr_type = chan->dst_type;
} else {
la->l2_psm = chan->sport;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
bacpy(&la->l2_bdaddr, &chan->src);
la->l2_cid = cpu_to_le16(chan->scid);
la->l2_bdaddr_type = chan->src_type;
}
return 0;
@ -660,10 +684,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (opt)
if (opt) {
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
else
set_bit(FLAG_DEFER_SETUP, &chan->flags);
} else {
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
clear_bit(FLAG_DEFER_SETUP, &chan->flags);
}
break;
case BT_FLUSHABLE:
@ -678,7 +705,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
}
if (opt == BT_FLUSHABLE_OFF) {
struct l2cap_conn *conn = chan->conn;
conn = chan->conn;
/* proceed further only when we have l2cap_conn and
No Flush support in the LM */
if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
@ -964,13 +991,12 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{
int err;
struct sock *sk = chan->data;
struct l2cap_pinfo *pi = l2cap_pi(sk);
int err;
lock_sock(sk);
if (pi->rx_busy_skb) {
if (l2cap_pi(sk)->rx_busy_skb) {
err = -ENOMEM;
goto done;
}
@ -986,9 +1012,9 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
* acked and reassembled until there is buffer space
* available.
*/
if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) {
pi->rx_busy_skb = skb;
l2cap_chan_busy(pi->chan, 1);
if (err < 0 && chan->mode == L2CAP_MODE_ERTM) {
l2cap_pi(sk)->rx_busy_skb = skb;
l2cap_chan_busy(chan, 1);
err = 0;
}
@ -1098,6 +1124,14 @@ static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
parent->sk_data_ready(parent, 0);
}
static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
sk->sk_state_change(sk);
}
static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
@ -1107,6 +1141,7 @@ static struct l2cap_ops l2cap_chan_ops = {
.state_change = l2cap_sock_state_change_cb,
.ready = l2cap_sock_ready_cb,
.defer = l2cap_sock_defer_cb,
.resume = l2cap_sock_resume_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb,
};
@ -1116,6 +1151,7 @@ static void l2cap_sock_destruct(struct sock *sk)
if (l2cap_pi(sk)->chan)
l2cap_chan_put(l2cap_pi(sk)->chan);
if (l2cap_pi(sk)->rx_busy_skb) {
kfree_skb(l2cap_pi(sk)->rx_busy_skb);
l2cap_pi(sk)->rx_busy_skb = NULL;
@ -1125,10 +1161,22 @@ static void l2cap_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue);
}
static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
int *msg_namelen)
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name;
memset(la, 0, sizeof(struct sockaddr_l2));
la->l2_family = AF_BLUETOOTH;
la->l2_psm = bt_cb(skb)->psm;
bacpy(&la->l2_bdaddr, &bt_cb(skb)->bdaddr);
*msg_namelen = sizeof(struct sockaddr_l2);
}
static void l2cap_sock_init(struct sock *sk, struct sock *parent)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
struct l2cap_chan *chan = pi->chan;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
BT_DBG("sk %p", sk);
@ -1152,13 +1200,13 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
security_sk_clone(parent, sk);
} else {
switch (sk->sk_type) {
case SOCK_RAW:
chan->chan_type = L2CAP_CHAN_RAW;
break;
case SOCK_DGRAM:
chan->chan_type = L2CAP_CHAN_CONN_LESS;
bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name;
break;
case SOCK_SEQPACKET:
case SOCK_STREAM:

File diff suppressed because it is too large Load diff

View file

@ -641,13 +641,13 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
{
struct rfcomm_session *s;
struct list_head *p, *n;
struct bt_sock *sk;
struct l2cap_chan *chan;
list_for_each_safe(p, n, &session_list) {
s = list_entry(p, struct rfcomm_session, list);
sk = bt_sk(s->sock->sk);
chan = l2cap_pi(s->sock->sk)->chan;
if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) &&
!bacmp(&sk->dst, dst))
if ((!bacmp(src, BDADDR_ANY) || !bacmp(&chan->src, src)) &&
!bacmp(&chan->dst, dst))
return s;
}
return NULL;
@ -732,11 +732,11 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
{
struct sock *sk = s->sock->sk;
struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
if (src)
bacpy(src, &bt_sk(sk)->src);
bacpy(src, &chan->src);
if (dst)
bacpy(dst, &bt_sk(sk)->dst);
bacpy(dst, &chan->dst);
}
/* ---- RFCOMM frame sending ---- */
@ -2112,12 +2112,11 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
rfcomm_lock();
list_for_each_entry(s, &session_list, list) {
struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
struct rfcomm_dlc *d;
list_for_each_entry(d, &s->dlcs, list) {
struct sock *sk = s->sock->sk;
seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
&bt_sk(sk)->src, &bt_sk(sk)->dst,
&chan->src, &chan->dst,
d->state, d->dlci, d->mtu,
d->rx_credits, d->tx_credits);
}

View file

@ -87,7 +87,8 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
parent->sk_data_ready(parent, 0);
} else {
if (d->state == BT_CONNECTED)
rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL);
rfcomm_session_getaddr(d->session,
&rfcomm_pi(sk)->src, NULL);
sk->sk_state_change(sk);
}
@ -110,7 +111,7 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
sk_for_each(sk, &rfcomm_sk_list.head) {
if (rfcomm_pi(sk)->channel == channel &&
!bacmp(&bt_sk(sk)->src, src))
!bacmp(&rfcomm_pi(sk)->src, src))
break;
}
@ -132,11 +133,11 @@ static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *
if (rfcomm_pi(sk)->channel == channel) {
/* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src))
if (!bacmp(&rfcomm_pi(sk)->src, src))
break;
/* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
if (!bacmp(&rfcomm_pi(sk)->src, BDADDR_ANY))
sk1 = sk;
}
}
@ -355,7 +356,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
err = -EADDRINUSE;
} else {
/* Save source address */
bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr);
bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
rfcomm_pi(sk)->channel = sa->rc_channel;
sk->sk_state = BT_BOUND;
}
@ -393,13 +394,14 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
}
sk->sk_state = BT_CONNECT;
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
bacpy(&rfcomm_pi(sk)->dst, &sa->rc_bdaddr);
rfcomm_pi(sk)->channel = sa->rc_channel;
d->sec_level = rfcomm_pi(sk)->sec_level;
d->role_switch = rfcomm_pi(sk)->role_switch;
err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
err = rfcomm_dlc_open(d, &rfcomm_pi(sk)->src, &sa->rc_bdaddr,
sa->rc_channel);
if (!err)
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
@ -429,7 +431,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
}
if (!rfcomm_pi(sk)->channel) {
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *src = &rfcomm_pi(sk)->src;
u8 channel;
err = -EINVAL;
@ -530,9 +532,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
sa->rc_family = AF_BLUETOOTH;
sa->rc_channel = rfcomm_pi(sk)->channel;
if (peer)
bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst);
bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->dst);
else
bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src);
bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->src);
*len = sizeof(struct sockaddr_rc);
return 0;
@ -951,8 +953,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
rfcomm_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, &src);
bacpy(&bt_sk(sk)->dst, &dst);
bacpy(&rfcomm_pi(sk)->src, &src);
bacpy(&rfcomm_pi(sk)->dst, &dst);
rfcomm_pi(sk)->channel = channel;
sk->sk_state = BT_CONFIG;
@ -979,7 +981,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
sk_for_each(sk, &rfcomm_sk_list.head) {
seq_printf(f, "%pMR %pMR %d %d\n",
&bt_sk(sk)->src, &bt_sk(sk)->dst,
&rfcomm_pi(sk)->src, &rfcomm_pi(sk)->dst,
sk->sk_state, rfcomm_pi(sk)->channel);
}

View file

@ -92,9 +92,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
hcon->sco_data = conn;
conn->hcon = hcon;
conn->src = &hdev->bdaddr;
conn->dst = &hcon->dst;
if (hdev->sco_mtu > 0)
conn->mtu = hdev->sco_mtu;
else
@ -156,16 +153,14 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
static int sco_connect(struct sock *sk)
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
int err, type;
BT_DBG("%pMR -> %pMR", src, dst);
BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
hdev = hci_get_route(dst, src);
hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src);
if (!hdev)
return -EHOSTUNREACH;
@ -182,7 +177,8 @@ static int sco_connect(struct sock *sk)
goto done;
}
hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
sco_pi(sk)->setting);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done;
@ -196,7 +192,7 @@ static int sco_connect(struct sock *sk)
}
/* Update source addr of the socket */
bacpy(src, conn->src);
bacpy(&sco_pi(sk)->src, &hcon->src);
err = sco_chan_add(conn, sk, NULL);
if (err)
@ -270,7 +266,7 @@ static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
if (sk->sk_state != BT_LISTEN)
continue;
if (!bacmp(&bt_sk(sk)->src, ba))
if (!bacmp(&sco_pi(sk)->src, ba))
return sk;
}
@ -291,11 +287,11 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src)
continue;
/* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src))
if (!bacmp(&sco_pi(sk)->src, src))
break;
/* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
if (!bacmp(&sco_pi(sk)->src, BDADDR_ANY))
sk1 = sk;
}
@ -475,7 +471,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
goto done;
}
bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
bacpy(&sco_pi(sk)->src, &sa->sco_bdaddr);
sk->sk_state = BT_BOUND;
@ -505,7 +501,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
lock_sock(sk);
/* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
err = sco_connect(sk);
if (err)
@ -522,7 +518,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
static int sco_sock_listen(struct socket *sock, int backlog)
{
struct sock *sk = sock->sk;
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *src = &sco_pi(sk)->src;
int err = 0;
BT_DBG("sk %p backlog %d", sk, backlog);
@ -626,9 +622,9 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len
*len = sizeof(struct sockaddr_sco);
if (peer)
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst);
else
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src);
return 0;
}
@ -999,7 +995,7 @@ static void sco_conn_ready(struct sco_conn *conn)
} else {
sco_conn_lock(conn);
parent = sco_get_sock_listen(conn->src);
parent = sco_get_sock_listen(&conn->hcon->src);
if (!parent) {
sco_conn_unlock(conn);
return;
@ -1017,8 +1013,8 @@ static void sco_conn_ready(struct sco_conn *conn)
sco_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
bacpy(&sco_pi(sk)->src, &conn->hcon->src);
bacpy(&sco_pi(sk)->dst, &conn->hcon->dst);
hci_conn_hold(conn->hcon);
__sco_chan_add(conn, sk, parent);
@ -1051,8 +1047,8 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
if (sk->sk_state != BT_LISTEN)
continue;
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) ||
!bacmp(&sco_pi(sk)->src, BDADDR_ANY)) {
lm |= HCI_LM_ACCEPT;
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
@ -1111,8 +1107,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p)
read_lock(&sco_sk_list.lock);
sk_for_each(sk, &sco_sk_list.head) {
seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src,
&bt_sk(sk)->dst, sk->sk_state);
seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src,
&sco_pi(sk)->dst, sk->sk_state);
}
read_unlock(&sco_sk_list.lock);

View file

@ -28,7 +28,8 @@
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/mgmt.h>
#include <net/bluetooth/smp.h>
#include "smp.h"
#define SMP_TIMEOUT msecs_to_jiffies(30000)
@ -85,8 +86,8 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
}
static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
u8 _rat, bdaddr_t *ra, u8 res[16])
u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
u8 _rat, bdaddr_t *ra, u8 res[16])
{
u8 p1[16], p2[16];
int err;
@ -126,8 +127,8 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
return err;
}
static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
u8 r1[16], u8 r2[16], u8 _r[16])
static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
u8 r2[16], u8 _r[16])
{
int err;
@ -150,7 +151,7 @@ static int smp_rand(u8 *buf)
}
static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
u16 dlen, void *data)
u16 dlen, void *data)
{
struct sk_buff *skb;
struct l2cap_hdr *lh;
@ -213,9 +214,8 @@ static __u8 seclevel_to_authreq(__u8 sec_level)
}
static void build_pairing_cmd(struct l2cap_conn *conn,
struct smp_cmd_pairing *req,
struct smp_cmd_pairing *rsp,
__u8 authreq)
struct smp_cmd_pairing *req,
struct smp_cmd_pairing *rsp, __u8 authreq)
{
u8 dist_keys = 0;
@ -249,7 +249,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
struct smp_chan *smp = conn->smp_chan;
if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
(max_key_size < SMP_MIN_ENC_KEY_SIZE))
(max_key_size < SMP_MIN_ENC_KEY_SIZE))
return SMP_ENC_KEY_SIZE;
smp->enc_key_size = max_key_size;
@ -263,15 +263,15 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
if (send)
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason);
&reason);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
hcon->dst_type, HCI_ERROR_AUTH_FAILURE);
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
HCI_ERROR_AUTH_FAILURE);
cancel_delayed_work_sync(&conn->security_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
smp_chan_destroy(conn);
}
@ -309,8 +309,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
/* If either side has unknown io_caps, use JUST WORKS */
/* Otherwise, look up method from the table */
if (!(auth & SMP_AUTH_MITM) ||
local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY)
local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY)
method = JUST_WORKS;
else
method = gen_method[remote_io][local_io];
@ -354,10 +354,10 @@ 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, &hcon->dst,
hcon->type, hcon->dst_type);
else
ret = mgmt_user_confirm_request(hcon->hdev, conn->dst,
ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0);
@ -386,12 +386,13 @@ static void confirm_work(struct work_struct *work)
smp->tfm = tfm;
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);
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->src_type, &conn->hcon->src,
conn->hcon->dst_type, &conn->hcon->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->hcon->dst,
conn->hcon->src_type, &conn->hcon->src, res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
@ -425,11 +426,13 @@ static void random_work(struct work_struct *work)
BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
if (hcon->out)
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0,
conn->src, hcon->dst_type, conn->dst, res);
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->src_type, &hcon->src,
hcon->dst_type, &hcon->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, &hcon->dst,
hcon->src_type, &hcon->src, res);
if (ret) {
reason = SMP_UNSPECIFIED;
goto error;
@ -477,9 +480,9 @@ static void random_work(struct work_struct *work)
swap128(key, stk);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size,
ediv, rand);
}
@ -494,7 +497,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
{
struct smp_chan *smp;
smp = kzalloc(sizeof(struct smp_chan), GFP_ATOMIC);
smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
if (!smp)
return NULL;
@ -649,7 +652,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
if ((req->auth_req & SMP_AUTH_BONDING) &&
(rsp->auth_req & SMP_AUTH_BONDING))
(rsp->auth_req & SMP_AUTH_BONDING))
auth = SMP_AUTH_BONDING;
auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
@ -684,7 +687,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
swap128(smp->prnd, random);
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
random);
random);
} else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
queue_work(hdev->workqueue, &smp->confirm);
} else {
@ -714,7 +717,7 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
key = hci_find_ltk_by_addr(hcon->hdev, conn->dst, hcon->dst_type);
key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type);
if (!key)
return 0;
@ -728,8 +731,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
hcon->enc_key_size = key->enc_size;
return 1;
}
static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_security_req *rp = (void *) skb->data;
@ -835,9 +838,9 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
skb_pull(skb, sizeof(*rp));
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,
authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
hci_add_ltk(hdev, &hcon->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);
@ -985,7 +988,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
authenticated = hcon->sec_level == BT_SECURITY_HIGH;
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_LTK_SLAVE, 1, authenticated,
enc.ltk, smp->enc_key_size, ediv, ident.rand);
@ -1007,10 +1010,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
/* Just public address */
memset(&addrinfo, 0, sizeof(addrinfo));
bacpy(&addrinfo.bdaddr, conn->src);
bacpy(&addrinfo.bdaddr, &conn->hcon->src);
smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
&addrinfo);
&addrinfo);
*keydist &= ~SMP_DIST_ID_KEY;
}