mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
This commit is contained in:
commit
bb400801c2
@ -40,7 +40,7 @@
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
||||
#define VERSION "1.2"
|
||||
#define VERSION "1.3"
|
||||
|
||||
static int minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
@ -51,14 +51,8 @@ struct vhci_data {
|
||||
|
||||
wait_queue_head_t read_wait;
|
||||
struct sk_buff_head readq;
|
||||
|
||||
struct fasync_struct *fasync;
|
||||
};
|
||||
|
||||
#define VHCI_FASYNC 0x0010
|
||||
|
||||
static struct miscdevice vhci_miscdev;
|
||||
|
||||
static int vhci_open_dev(struct hci_dev *hdev)
|
||||
{
|
||||
set_bit(HCI_RUNNING, &hdev->flags);
|
||||
@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb)
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&data->readq, skb);
|
||||
|
||||
if (data->flags & VHCI_FASYNC)
|
||||
kill_fasync(&data->fasync, SIGIO, POLL_IN);
|
||||
|
||||
wake_up_interruptible(&data->read_wait);
|
||||
|
||||
return 0;
|
||||
@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
|
||||
static ssize_t vhci_read(struct file *file,
|
||||
char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
struct vhci_data *data = file->private_data;
|
||||
struct sk_buff *skb;
|
||||
ssize_t ret = 0;
|
||||
|
||||
add_wait_queue(&data->read_wait, &wait);
|
||||
while (count) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
skb = skb_dequeue(&data->readq);
|
||||
if (!skb) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
schedule();
|
||||
continue;
|
||||
if (skb) {
|
||||
ret = vhci_put_user(data, skb, buf, count);
|
||||
if (ret < 0)
|
||||
skb_queue_head(&data->readq, skb);
|
||||
else
|
||||
kfree_skb(skb);
|
||||
break;
|
||||
}
|
||||
|
||||
if (access_ok(VERIFY_WRITE, buf, count))
|
||||
ret = vhci_put_user(data, skb, buf, count);
|
||||
else
|
||||
ret = -EFAULT;
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
break;
|
||||
ret = wait_event_interruptible(data->read_wait,
|
||||
!skb_queue_empty(&data->readq));
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&data->read_wait, &wait);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file,
|
||||
{
|
||||
struct vhci_data *data = file->private_data;
|
||||
|
||||
if (!access_ok(VERIFY_READ, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
return vhci_get_user(data, buf, count);
|
||||
}
|
||||
|
||||
@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file)
|
||||
skb_queue_head_init(&data->readq);
|
||||
init_waitqueue_head(&data->read_wait);
|
||||
|
||||
lock_kernel();
|
||||
hdev = hci_alloc_dev();
|
||||
if (!hdev) {
|
||||
kfree(data);
|
||||
unlock_kernel();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file)
|
||||
BT_ERR("Can't register HCI device");
|
||||
kfree(data);
|
||||
hci_free_dev(hdev);
|
||||
unlock_kernel();
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
file->private_data = data;
|
||||
unlock_kernel();
|
||||
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vhci_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
struct vhci_data *data = file->private_data;
|
||||
int err = 0;
|
||||
|
||||
lock_kernel();
|
||||
err = fasync_helper(fd, file, on, &data->fasync);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
if (on)
|
||||
data->flags |= VHCI_FASYNC;
|
||||
else
|
||||
data->flags &= ~VHCI_FASYNC;
|
||||
|
||||
out:
|
||||
unlock_kernel();
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct file_operations vhci_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = vhci_read,
|
||||
.write = vhci_write,
|
||||
.poll = vhci_poll,
|
||||
.ioctl = vhci_ioctl,
|
||||
.open = vhci_open,
|
||||
.release = vhci_release,
|
||||
.fasync = vhci_fasync,
|
||||
};
|
||||
|
||||
static struct miscdevice vhci_miscdev= {
|
||||
.name = "vhci",
|
||||
.fops = &vhci_fops,
|
||||
.name = "vhci",
|
||||
.fops = &vhci_fops,
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
};
|
||||
|
||||
static int __init vhci_init(void)
|
||||
{
|
||||
BT_INFO("Virtual HCI driver ver %s", VERSION);
|
||||
|
||||
vhci_miscdev.minor = minor;
|
||||
|
||||
if (misc_register(&vhci_miscdev) < 0) {
|
||||
BT_ERR("Can't register misc device with minor %d", minor);
|
||||
return -EIO;
|
||||
@ -369,9 +320,6 @@ static void __exit vhci_exit(void)
|
||||
module_init(vhci_init);
|
||||
module_exit(vhci_exit);
|
||||
|
||||
module_param(minor, int, 0444);
|
||||
MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
|
||||
|
||||
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
||||
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
|
||||
MODULE_VERSION(VERSION);
|
||||
|
@ -81,12 +81,6 @@ enum {
|
||||
BT_CLOSED
|
||||
};
|
||||
|
||||
/* Endianness conversions */
|
||||
#define htobs(a) __cpu_to_le16(a)
|
||||
#define htobl(a) __cpu_to_le32(a)
|
||||
#define btohs(a) __le16_to_cpu(a)
|
||||
#define btohl(a) __le32_to_cpu(a)
|
||||
|
||||
/* BD Address */
|
||||
typedef struct {
|
||||
__u8 b[6];
|
||||
|
@ -137,6 +137,8 @@ struct hci_dev {
|
||||
struct device *parent;
|
||||
struct device dev;
|
||||
|
||||
struct rfkill *rfkill;
|
||||
|
||||
struct module *owner;
|
||||
|
||||
int (*open)(struct hci_dev *hdev);
|
||||
|
@ -26,8 +26,13 @@
|
||||
#define __L2CAP_H
|
||||
|
||||
/* L2CAP defaults */
|
||||
#define L2CAP_DEFAULT_MTU 672
|
||||
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
|
||||
#define L2CAP_DEFAULT_MTU 672
|
||||
#define L2CAP_DEFAULT_FLUSH_TO 0xffff
|
||||
#define L2CAP_DEFAULT_RX_WINDOW 1
|
||||
#define L2CAP_DEFAULT_MAX_RECEIVE 1
|
||||
#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */
|
||||
#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */
|
||||
#define L2CAP_DEFAULT_MAX_RX_APDU 0xfff7
|
||||
|
||||
#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
|
||||
#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
|
||||
@ -64,17 +69,29 @@ struct l2cap_conninfo {
|
||||
#define L2CAP_LM_SECURE 0x0020
|
||||
|
||||
/* L2CAP command codes */
|
||||
#define L2CAP_COMMAND_REJ 0x01
|
||||
#define L2CAP_CONN_REQ 0x02
|
||||
#define L2CAP_CONN_RSP 0x03
|
||||
#define L2CAP_CONF_REQ 0x04
|
||||
#define L2CAP_CONF_RSP 0x05
|
||||
#define L2CAP_DISCONN_REQ 0x06
|
||||
#define L2CAP_DISCONN_RSP 0x07
|
||||
#define L2CAP_ECHO_REQ 0x08
|
||||
#define L2CAP_ECHO_RSP 0x09
|
||||
#define L2CAP_INFO_REQ 0x0a
|
||||
#define L2CAP_INFO_RSP 0x0b
|
||||
#define L2CAP_COMMAND_REJ 0x01
|
||||
#define L2CAP_CONN_REQ 0x02
|
||||
#define L2CAP_CONN_RSP 0x03
|
||||
#define L2CAP_CONF_REQ 0x04
|
||||
#define L2CAP_CONF_RSP 0x05
|
||||
#define L2CAP_DISCONN_REQ 0x06
|
||||
#define L2CAP_DISCONN_RSP 0x07
|
||||
#define L2CAP_ECHO_REQ 0x08
|
||||
#define L2CAP_ECHO_RSP 0x09
|
||||
#define L2CAP_INFO_REQ 0x0a
|
||||
#define L2CAP_INFO_RSP 0x0b
|
||||
|
||||
/* L2CAP feature mask */
|
||||
#define L2CAP_FEAT_FLOWCTL 0x00000001
|
||||
#define L2CAP_FEAT_RETRANS 0x00000002
|
||||
#define L2CAP_FEAT_ERTM 0x00000008
|
||||
#define L2CAP_FEAT_STREAMING 0x00000010
|
||||
#define L2CAP_FEAT_FCS 0x00000020
|
||||
#define L2CAP_FEAT_FIXED_CHAN 0x00000080
|
||||
|
||||
/* L2CAP checksum option */
|
||||
#define L2CAP_FCS_NONE 0x00
|
||||
#define L2CAP_FCS_CRC16 0x01
|
||||
|
||||
/* L2CAP structures */
|
||||
struct l2cap_hdr {
|
||||
@ -106,17 +123,23 @@ struct l2cap_conn_rsp {
|
||||
__le16 status;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* channel indentifier */
|
||||
#define L2CAP_CID_SIGNALING 0x0001
|
||||
#define L2CAP_CID_CONN_LESS 0x0002
|
||||
#define L2CAP_CID_DYN_START 0x0040
|
||||
#define L2CAP_CID_DYN_END 0xffff
|
||||
|
||||
/* connect result */
|
||||
#define L2CAP_CR_SUCCESS 0x0000
|
||||
#define L2CAP_CR_PEND 0x0001
|
||||
#define L2CAP_CR_BAD_PSM 0x0002
|
||||
#define L2CAP_CR_SEC_BLOCK 0x0003
|
||||
#define L2CAP_CR_NO_MEM 0x0004
|
||||
#define L2CAP_CR_SUCCESS 0x0000
|
||||
#define L2CAP_CR_PEND 0x0001
|
||||
#define L2CAP_CR_BAD_PSM 0x0002
|
||||
#define L2CAP_CR_SEC_BLOCK 0x0003
|
||||
#define L2CAP_CR_NO_MEM 0x0004
|
||||
|
||||
/* connect status */
|
||||
#define L2CAP_CS_NO_INFO 0x0000
|
||||
#define L2CAP_CS_AUTHEN_PEND 0x0001
|
||||
#define L2CAP_CS_AUTHOR_PEND 0x0002
|
||||
#define L2CAP_CS_NO_INFO 0x0000
|
||||
#define L2CAP_CS_AUTHEN_PEND 0x0001
|
||||
#define L2CAP_CS_AUTHOR_PEND 0x0002
|
||||
|
||||
struct l2cap_conf_req {
|
||||
__le16 dcid;
|
||||
@ -143,10 +166,14 @@ struct l2cap_conf_opt {
|
||||
} __attribute__ ((packed));
|
||||
#define L2CAP_CONF_OPT_SIZE 2
|
||||
|
||||
#define L2CAP_CONF_HINT 0x80
|
||||
#define L2CAP_CONF_MASK 0x7f
|
||||
|
||||
#define L2CAP_CONF_MTU 0x01
|
||||
#define L2CAP_CONF_FLUSH_TO 0x02
|
||||
#define L2CAP_CONF_QOS 0x03
|
||||
#define L2CAP_CONF_RFC 0x04
|
||||
#define L2CAP_CONF_FCS 0x05
|
||||
|
||||
#define L2CAP_CONF_MAX_SIZE 22
|
||||
|
||||
@ -162,6 +189,8 @@ struct l2cap_conf_rfc {
|
||||
#define L2CAP_MODE_BASIC 0x00
|
||||
#define L2CAP_MODE_RETRANS 0x01
|
||||
#define L2CAP_MODE_FLOWCTL 0x02
|
||||
#define L2CAP_MODE_ERTM 0x03
|
||||
#define L2CAP_MODE_STREAM 0x04
|
||||
|
||||
struct l2cap_disconn_req {
|
||||
__le16 dcid;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/rfkill.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
|
||||
|
||||
hci_req_lock(hdev);
|
||||
|
||||
if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
|
||||
ret = -ERFKILL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (test_bit(HCI_UP, &hdev->flags)) {
|
||||
ret = -EALREADY;
|
||||
goto done;
|
||||
@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
|
||||
|
||||
/* ---- Interface to HCI drivers ---- */
|
||||
|
||||
static int hci_rfkill_set_block(void *data, bool blocked)
|
||||
{
|
||||
struct hci_dev *hdev = data;
|
||||
|
||||
BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
|
||||
|
||||
if (!blocked)
|
||||
return 0;
|
||||
|
||||
hci_dev_do_close(hdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rfkill_ops hci_rfkill_ops = {
|
||||
.set_block = hci_rfkill_set_block,
|
||||
};
|
||||
|
||||
/* Alloc HCI device */
|
||||
struct hci_dev *hci_alloc_dev(void)
|
||||
{
|
||||
@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
|
||||
struct list_head *head = &hci_dev_list, *p;
|
||||
int i, id = 0;
|
||||
|
||||
BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
|
||||
BT_DBG("%p name %s type %d owner %p", hdev, hdev->name,
|
||||
hdev->type, hdev->owner);
|
||||
|
||||
if (!hdev->open || !hdev->close || !hdev->destruct)
|
||||
return -EINVAL;
|
||||
@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
|
||||
|
||||
hci_register_sysfs(hdev);
|
||||
|
||||
hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
|
||||
RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
|
||||
if (hdev->rfkill) {
|
||||
if (rfkill_register(hdev->rfkill) < 0) {
|
||||
rfkill_destroy(hdev->rfkill);
|
||||
hdev->rfkill = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hci_notify(hdev, HCI_DEV_REG);
|
||||
|
||||
return id;
|
||||
@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
|
||||
|
||||
hci_notify(hdev, HCI_DEV_UNREG);
|
||||
|
||||
if (hdev->rfkill) {
|
||||
rfkill_unregister(hdev->rfkill);
|
||||
rfkill_destroy(hdev->rfkill);
|
||||
}
|
||||
|
||||
hci_unregister_sysfs(hdev);
|
||||
|
||||
__hci_dev_put(hdev);
|
||||
|
@ -40,10 +40,10 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
@ -52,7 +52,7 @@
|
||||
|
||||
#define VERSION "2.13"
|
||||
|
||||
static u32 l2cap_feat_mask = 0x0080;
|
||||
static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
|
||||
static u8 l2cap_fixed_chan[8] = { 0x02, };
|
||||
|
||||
static const struct proto_ops l2cap_sock_ops;
|
||||
@ -134,7 +134,8 @@ static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16
|
||||
struct sock *s;
|
||||
read_lock(&l->lock);
|
||||
s = __l2cap_get_chan_by_scid(l, cid);
|
||||
if (s) bh_lock_sock(s);
|
||||
if (s)
|
||||
bh_lock_sock(s);
|
||||
read_unlock(&l->lock);
|
||||
return s;
|
||||
}
|
||||
@ -154,17 +155,18 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8
|
||||
struct sock *s;
|
||||
read_lock(&l->lock);
|
||||
s = __l2cap_get_chan_by_ident(l, ident);
|
||||
if (s) bh_lock_sock(s);
|
||||
if (s)
|
||||
bh_lock_sock(s);
|
||||
read_unlock(&l->lock);
|
||||
return s;
|
||||
}
|
||||
|
||||
static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
|
||||
{
|
||||
u16 cid = 0x0040;
|
||||
u16 cid = L2CAP_CID_DYN_START;
|
||||
|
||||
for (; cid < 0xffff; cid++) {
|
||||
if(!__l2cap_get_chan_by_scid(l, cid))
|
||||
for (; cid < L2CAP_CID_DYN_END; cid++) {
|
||||
if (!__l2cap_get_chan_by_scid(l, cid))
|
||||
return cid;
|
||||
}
|
||||
|
||||
@ -204,7 +206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
|
||||
{
|
||||
struct l2cap_chan_list *l = &conn->chan_list;
|
||||
|
||||
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
|
||||
BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
|
||||
l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
|
||||
|
||||
conn->disc_reason = 0x13;
|
||||
|
||||
@ -215,13 +218,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
|
||||
l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
|
||||
} else if (sk->sk_type == SOCK_DGRAM) {
|
||||
/* Connectionless socket */
|
||||
l2cap_pi(sk)->scid = 0x0002;
|
||||
l2cap_pi(sk)->dcid = 0x0002;
|
||||
l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
|
||||
l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
|
||||
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
|
||||
} else {
|
||||
/* Raw socket can send/recv signalling messages only */
|
||||
l2cap_pi(sk)->scid = 0x0001;
|
||||
l2cap_pi(sk)->dcid = 0x0001;
|
||||
l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
|
||||
l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
|
||||
l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
|
||||
}
|
||||
|
||||
@ -272,7 +275,7 @@ static inline int l2cap_check_security(struct sock *sk)
|
||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
|
||||
auth_type = HCI_AT_NO_BONDING_MITM;
|
||||
else
|
||||
auth_type = HCI_AT_NO_BONDING;
|
||||
auth_type = HCI_AT_NO_BONDING;
|
||||
|
||||
if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
|
||||
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
|
||||
@ -588,7 +591,8 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t
|
||||
struct sock *s;
|
||||
read_lock(&l2cap_sk_list.lock);
|
||||
s = __l2cap_get_sock_by_psm(state, psm, src);
|
||||
if (s) bh_lock_sock(s);
|
||||
if (s)
|
||||
bh_lock_sock(s);
|
||||
read_unlock(&l2cap_sk_list.lock);
|
||||
return s;
|
||||
}
|
||||
@ -808,7 +812,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (la.l2_psm && btohs(la.l2_psm) < 0x1001 &&
|
||||
if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
|
||||
!capable(CAP_NET_BIND_SERVICE)) {
|
||||
err = -EACCES;
|
||||
goto done;
|
||||
@ -825,7 +829,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
|
||||
l2cap_pi(sk)->sport = la.l2_psm;
|
||||
sk->sk_state = BT_BOUND;
|
||||
|
||||
if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003)
|
||||
if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
|
||||
__le16_to_cpu(la.l2_psm) == 0x0003)
|
||||
l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
|
||||
}
|
||||
|
||||
@ -844,12 +849,13 @@ static int l2cap_do_connect(struct sock *sk)
|
||||
struct hci_conn *hcon;
|
||||
struct hci_dev *hdev;
|
||||
__u8 auth_type;
|
||||
int err = 0;
|
||||
int err;
|
||||
|
||||
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
|
||||
l2cap_pi(sk)->psm);
|
||||
|
||||
if (!(hdev = hci_get_route(dst, src)))
|
||||
hdev = hci_get_route(dst, src);
|
||||
if (!hdev)
|
||||
return -EHOSTUNREACH;
|
||||
|
||||
hci_dev_lock_bh(hdev);
|
||||
@ -950,7 +956,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch(sk->sk_state) {
|
||||
switch (sk->sk_state) {
|
||||
case BT_CONNECT:
|
||||
case BT_CONNECT2:
|
||||
case BT_CONFIG:
|
||||
@ -975,7 +981,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
|
||||
bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
|
||||
l2cap_pi(sk)->psm = la.l2_psm;
|
||||
|
||||
if ((err = l2cap_do_connect(sk)))
|
||||
err = l2cap_do_connect(sk);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
wait:
|
||||
@ -1009,9 +1016,9 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
|
||||
write_lock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
for (psm = 0x1001; psm < 0x1100; psm += 2)
|
||||
if (!__l2cap_get_sock_by_addr(htobs(psm), src)) {
|
||||
l2cap_pi(sk)->psm = htobs(psm);
|
||||
l2cap_pi(sk)->sport = htobs(psm);
|
||||
if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
|
||||
l2cap_pi(sk)->psm = cpu_to_le16(psm);
|
||||
l2cap_pi(sk)->sport = cpu_to_le16(psm);
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
@ -1100,11 +1107,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
|
||||
if (peer) {
|
||||
la->l2_psm = l2cap_pi(sk)->psm;
|
||||
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
|
||||
la->l2_cid = htobs(l2cap_pi(sk)->dcid);
|
||||
la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
|
||||
} else {
|
||||
la->l2_psm = l2cap_pi(sk)->sport;
|
||||
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
|
||||
la->l2_cid = htobs(l2cap_pi(sk)->scid);
|
||||
la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1114,7 +1121,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
|
||||
{
|
||||
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
|
||||
struct sk_buff *skb, **frag;
|
||||
int err, hlen, count, sent=0;
|
||||
int err, hlen, count, sent = 0;
|
||||
struct l2cap_hdr *lh;
|
||||
|
||||
BT_DBG("sk %p len %d", sk, len);
|
||||
@ -1167,8 +1174,8 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
|
||||
|
||||
frag = &(*frag)->next;
|
||||
}
|
||||
|
||||
if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
|
||||
err = hci_send_acl(conn->hcon, skb, 0);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
return sent;
|
||||
@ -1556,7 +1563,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
{
|
||||
struct l2cap_chan_list *l = &conn->chan_list;
|
||||
struct sk_buff *nskb;
|
||||
struct sock * sk;
|
||||
struct sock *sk;
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
@ -1568,8 +1575,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
/* Don't send frame to the socket it came from */
|
||||
if (skb->sk == sk)
|
||||
continue;
|
||||
|
||||
if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
continue;
|
||||
|
||||
if (sock_queue_rcv_skb(sk, nskb))
|
||||
@ -1587,7 +1594,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
|
||||
struct l2cap_hdr *lh;
|
||||
int len, count;
|
||||
|
||||
BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
|
||||
BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
|
||||
conn, code, ident, dlen);
|
||||
|
||||
len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
|
||||
count = min_t(unsigned int, conn->mtu, len);
|
||||
@ -1598,7 +1606,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
|
||||
|
||||
lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
|
||||
lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
|
||||
lh->cid = cpu_to_le16(0x0001);
|
||||
lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
|
||||
|
||||
cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
|
||||
cmd->code = code;
|
||||
@ -1739,8 +1747,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
|
||||
while (len >= L2CAP_CONF_OPT_SIZE) {
|
||||
len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
|
||||
|
||||
hint = type & 0x80;
|
||||
type &= 0x7f;
|
||||
hint = type & L2CAP_CONF_HINT;
|
||||
type &= L2CAP_CONF_MASK;
|
||||
|
||||
switch (type) {
|
||||
case L2CAP_CONF_MTU:
|
||||
@ -1966,10 +1974,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
|
||||
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
|
||||
|
||||
if (scid) {
|
||||
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
|
||||
sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
|
||||
if (!sk)
|
||||
return 0;
|
||||
} else {
|
||||
if (!(sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident)))
|
||||
sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
|
||||
if (!sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2012,7 +2022,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
||||
|
||||
BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
|
||||
|
||||
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
|
||||
sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
|
||||
if (!sk)
|
||||
return -ENOENT;
|
||||
|
||||
if (sk->sk_state == BT_DISCONN)
|
||||
@ -2079,9 +2090,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
||||
flags = __le16_to_cpu(rsp->flags);
|
||||
result = __le16_to_cpu(rsp->result);
|
||||
|
||||
BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
|
||||
BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
|
||||
scid, flags, result);
|
||||
|
||||
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
|
||||
sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
||||
switch (result) {
|
||||
@ -2142,7 +2155,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
|
||||
|
||||
BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
|
||||
|
||||
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
|
||||
sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
||||
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
|
||||
@ -2169,7 +2183,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
|
||||
|
||||
BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
|
||||
|
||||
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
|
||||
sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
||||
l2cap_chan_del(sk, 0);
|
||||
@ -2230,7 +2245,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
|
||||
if (type == L2CAP_IT_FEAT_MASK) {
|
||||
conn->feat_mask = get_unaligned_le32(rsp->data);
|
||||
|
||||
if (conn->feat_mask & 0x0080) {
|
||||
if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
|
||||
struct l2cap_info_req req;
|
||||
req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
|
||||
|
||||
@ -2403,7 +2418,8 @@ drop:
|
||||
kfree_skb(skb);
|
||||
|
||||
done:
|
||||
if (sk) bh_unlock_sock(sk);
|
||||
if (sk)
|
||||
bh_unlock_sock(sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2420,11 +2436,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
BT_DBG("len %d, cid 0x%4.4x", len, cid);
|
||||
|
||||
switch (cid) {
|
||||
case 0x0001:
|
||||
case L2CAP_CID_SIGNALING:
|
||||
l2cap_sig_channel(conn, skb);
|
||||
break;
|
||||
|
||||
case 0x0002:
|
||||
case L2CAP_CID_CONN_LESS:
|
||||
psm = get_unaligned((__le16 *) skb->data);
|
||||
skb_pull(skb, 2);
|
||||
l2cap_conless_channel(conn, psm, skb);
|
||||
@ -2650,7 +2666,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
|
||||
}
|
||||
|
||||
/* Allocate skb for the complete frame (with header) */
|
||||
if (!(conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC)))
|
||||
conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
|
||||
if (!conn->rx_skb)
|
||||
goto drop;
|
||||
|
||||
skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
|
||||
@ -2704,13 +2721,13 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
|
||||
|
||||
str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid,
|
||||
pi->imtu, pi->omtu, pi->sec_level);
|
||||
sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
|
||||
pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
|
||||
}
|
||||
|
||||
read_unlock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
return str - buf;
|
||||
}
|
||||
|
||||
static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
|
||||
|
@ -679,7 +679,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
|
||||
|
||||
bacpy(&addr.l2_bdaddr, dst);
|
||||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = htobs(RFCOMM_PSM);
|
||||
addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
|
||||
addr.l2_cid = 0;
|
||||
*err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
|
||||
if (*err == 0 || *err == -EINPROGRESS)
|
||||
@ -852,9 +852,9 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
|
||||
}
|
||||
|
||||
if (cr && channel_mtu >= 0)
|
||||
pn->mtu = htobs(channel_mtu);
|
||||
pn->mtu = cpu_to_le16(channel_mtu);
|
||||
else
|
||||
pn->mtu = htobs(d->mtu);
|
||||
pn->mtu = cpu_to_le16(d->mtu);
|
||||
|
||||
*ptr = __fcs(buf); ptr++;
|
||||
|
||||
@ -1056,7 +1056,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
|
||||
|
||||
if (len > 127) {
|
||||
hdr = (void *) skb_push(skb, 4);
|
||||
put_unaligned(htobs(__len16(len)), (__le16 *) &hdr->len);
|
||||
put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
|
||||
} else {
|
||||
hdr = (void *) skb_push(skb, 3);
|
||||
hdr->len = __len8(len);
|
||||
@ -1289,7 +1289,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
|
||||
|
||||
d->priority = pn->priority;
|
||||
|
||||
d->mtu = btohs(pn->mtu);
|
||||
d->mtu = __le16_to_cpu(pn->mtu);
|
||||
|
||||
if (cr && d->mtu > s->mtu)
|
||||
d->mtu = s->mtu;
|
||||
@ -1922,7 +1922,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
|
||||
/* Bind socket */
|
||||
bacpy(&addr.l2_bdaddr, ba);
|
||||
addr.l2_family = AF_BLUETOOTH;
|
||||
addr.l2_psm = htobs(RFCOMM_PSM);
|
||||
addr.l2_psm = cpu_to_le16(RFCOMM_PSM);
|
||||
addr.l2_cid = 0;
|
||||
err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (err < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user