Commit b231070a authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents b6b561c3 4b836f39
......@@ -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 },
......
......@@ -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");
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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:
......
......@@ -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))
......
......@@ -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;
......
......@@ -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
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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),
......
......@@ -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;
......
......@@ -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);
/* 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 = hci_conn_add(hdev, LE_LINK, dst);
if (!le)
return ERR_PTR(-ENOMEM);
/* 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);
conn = hci_conn_add(hdev, LE_LINK, dst);
if (!conn)
return ERR_PTR(-ENOMEM);
le->dst_type = bdaddr_to_le(dst_type);
hci_le_create_connection(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;
}
le->pending_sec_level = sec_level;
le->auth_type = auth_type;
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;
hci_conn_hold(le);
err = hci_create_le_conn(conn);
if (err)
return ERR_PTR(err);
return le;
done:
hci_conn_hold(conn);
return conn;
}
static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
......
This diff is collapsed.
......@@ -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);
}
......
......@@ -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) {
......
......@@ -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;
......
This diff is collapsed.
......@@ -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:
......
This diff is collapsed.
......@@ -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);
}
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment