Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
bb400801
Commit
bb400801
authored
Jun 11, 2009
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
parents
130aa61a
611b30f7
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
184 additions
and
155 deletions
+184
-155
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+19
-71
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+0
-6
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+2
-0
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+50
-21
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+40
-1
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+67
-50
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+6
-6
No files found.
drivers/bluetooth/hci_vhci.c
View file @
bb400801
...
@@ -40,7 +40,7 @@
...
@@ -40,7 +40,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
#define VERSION "1.
2
"
#define VERSION "1.
3
"
static
int
minor
=
MISC_DYNAMIC_MINOR
;
static
int
minor
=
MISC_DYNAMIC_MINOR
;
...
@@ -51,14 +51,8 @@ struct vhci_data {
...
@@ -51,14 +51,8 @@ struct vhci_data {
wait_queue_head_t
read_wait
;
wait_queue_head_t
read_wait
;
struct
sk_buff_head
readq
;
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
)
static
int
vhci_open_dev
(
struct
hci_dev
*
hdev
)
{
{
set_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
set_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
...
@@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb)
...
@@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb)
memcpy
(
skb_push
(
skb
,
1
),
&
bt_cb
(
skb
)
->
pkt_type
,
1
);
memcpy
(
skb_push
(
skb
,
1
),
&
bt_cb
(
skb
)
->
pkt_type
,
1
);
skb_queue_tail
(
&
data
->
readq
,
skb
);
skb_queue_tail
(
&
data
->
readq
,
skb
);
if
(
data
->
flags
&
VHCI_FASYNC
)
kill_fasync
(
&
data
->
fasync
,
SIGIO
,
POLL_IN
);
wake_up_interruptible
(
&
data
->
read_wait
);
wake_up_interruptible
(
&
data
->
read_wait
);
return
0
;
return
0
;
...
@@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
...
@@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
static
ssize_t
vhci_read
(
struct
file
*
file
,
static
ssize_t
vhci_read
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
pos
)
char
__user
*
buf
,
size_t
count
,
loff_t
*
pos
)
{
{
DECLARE_WAITQUEUE
(
wait
,
current
);
struct
vhci_data
*
data
=
file
->
private_data
;
struct
vhci_data
*
data
=
file
->
private_data
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
ssize_t
ret
=
0
;
ssize_t
ret
=
0
;
add_wait_queue
(
&
data
->
read_wait
,
&
wait
);
while
(
count
)
{
while
(
count
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
skb
=
skb_dequeue
(
&
data
->
readq
);
skb
=
skb_dequeue
(
&
data
->
readq
);
if
(
!
skb
)
{
if
(
skb
)
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
ret
=
vhci_put_user
(
data
,
skb
,
buf
,
count
);
ret
=
-
EAGAIN
;
if
(
ret
<
0
)
break
;
skb_queue_head
(
&
data
->
readq
,
skb
);
}
else
kfree_skb
(
skb
);
if
(
signal_pending
(
current
))
{
break
;
ret
=
-
ERESTARTSYS
;
break
;
}
schedule
();
continue
;
}
}
if
(
access_ok
(
VERIFY_WRITE
,
buf
,
count
))
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
ret
=
vhci_put_user
(
data
,
skb
,
buf
,
count
)
;
ret
=
-
EAGAIN
;
else
break
;
ret
=
-
EFAULT
;
}
kfree_skb
(
skb
);
ret
=
wait_event_interruptible
(
data
->
read_wait
,
break
;
!
skb_queue_empty
(
&
data
->
readq
));
if
(
ret
<
0
)
break
;
}
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
data
->
read_wait
,
&
wait
);
return
ret
;
return
ret
;
}
}
...
@@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file,
...
@@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file,
{
{
struct
vhci_data
*
data
=
file
->
private_data
;
struct
vhci_data
*
data
=
file
->
private_data
;
if
(
!
access_ok
(
VERIFY_READ
,
buf
,
count
))
return
-
EFAULT
;
return
vhci_get_user
(
data
,
buf
,
count
);
return
vhci_get_user
(
data
,
buf
,
count
);
}
}
...
@@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file)
...
@@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file)
skb_queue_head_init
(
&
data
->
readq
);
skb_queue_head_init
(
&
data
->
readq
);
init_waitqueue_head
(
&
data
->
read_wait
);
init_waitqueue_head
(
&
data
->
read_wait
);
lock_kernel
();
hdev
=
hci_alloc_dev
();
hdev
=
hci_alloc_dev
();
if
(
!
hdev
)
{
if
(
!
hdev
)
{
kfree
(
data
);
kfree
(
data
);
unlock_kernel
();
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file)
...
@@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file)
BT_ERR
(
"Can't register HCI device"
);
BT_ERR
(
"Can't register HCI device"
);
kfree
(
data
);
kfree
(
data
);
hci_free_dev
(
hdev
);
hci_free_dev
(
hdev
);
unlock_kernel
();
return
-
EBUSY
;
return
-
EBUSY
;
}
}
file
->
private_data
=
data
;
file
->
private_data
=
data
;
unlock_kernel
();
return
nonseekable_open
(
inode
,
file
);
return
nonseekable_open
(
inode
,
file
);
}
}
...
@@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file)
...
@@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file)
return
0
;
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
=
{
static
const
struct
file_operations
vhci_fops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
vhci_read
,
.
read
=
vhci_read
,
.
write
=
vhci_write
,
.
write
=
vhci_write
,
.
poll
=
vhci_poll
,
.
poll
=
vhci_poll
,
.
ioctl
=
vhci_ioctl
,
.
ioctl
=
vhci_ioctl
,
.
open
=
vhci_open
,
.
open
=
vhci_open
,
.
release
=
vhci_release
,
.
release
=
vhci_release
,
.
fasync
=
vhci_fasync
,
};
};
static
struct
miscdevice
vhci_miscdev
=
{
static
struct
miscdevice
vhci_miscdev
=
{
.
name
=
"vhci"
,
.
name
=
"vhci"
,
.
fops
=
&
vhci_fops
,
.
fops
=
&
vhci_fops
,
.
minor
=
MISC_DYNAMIC_MINOR
,
};
};
static
int
__init
vhci_init
(
void
)
static
int
__init
vhci_init
(
void
)
{
{
BT_INFO
(
"Virtual HCI driver ver %s"
,
VERSION
);
BT_INFO
(
"Virtual HCI driver ver %s"
,
VERSION
);
vhci_miscdev
.
minor
=
minor
;
if
(
misc_register
(
&
vhci_miscdev
)
<
0
)
{
if
(
misc_register
(
&
vhci_miscdev
)
<
0
)
{
BT_ERR
(
"Can't register misc device with minor %d"
,
minor
);
BT_ERR
(
"Can't register misc device with minor %d"
,
minor
);
return
-
EIO
;
return
-
EIO
;
...
@@ -369,9 +320,6 @@ static void __exit vhci_exit(void)
...
@@ -369,9 +320,6 @@ static void __exit vhci_exit(void)
module_init
(
vhci_init
);
module_init
(
vhci_init
);
module_exit
(
vhci_exit
);
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_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth virtual HCI driver ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth virtual HCI driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
include/net/bluetooth/bluetooth.h
View file @
bb400801
...
@@ -81,12 +81,6 @@ enum {
...
@@ -81,12 +81,6 @@ enum {
BT_CLOSED
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 */
/* BD Address */
typedef
struct
{
typedef
struct
{
__u8
b
[
6
];
__u8
b
[
6
];
...
...
include/net/bluetooth/hci_core.h
View file @
bb400801
...
@@ -137,6 +137,8 @@ struct hci_dev {
...
@@ -137,6 +137,8 @@ struct hci_dev {
struct
device
*
parent
;
struct
device
*
parent
;
struct
device
dev
;
struct
device
dev
;
struct
rfkill
*
rfkill
;
struct
module
*
owner
;
struct
module
*
owner
;
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
open
)(
struct
hci_dev
*
hdev
);
...
...
include/net/bluetooth/l2cap.h
View file @
bb400801
...
@@ -26,8 +26,13 @@
...
@@ -26,8 +26,13 @@
#define __L2CAP_H
#define __L2CAP_H
/* L2CAP defaults */
/* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
#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_CONN_TIMEOUT (40000)
/* 40 seconds */
#define L2CAP_INFO_TIMEOUT (4000)
/* 4 seconds */
#define L2CAP_INFO_TIMEOUT (4000)
/* 4 seconds */
...
@@ -64,17 +69,29 @@ struct l2cap_conninfo {
...
@@ -64,17 +69,29 @@ struct l2cap_conninfo {
#define L2CAP_LM_SECURE 0x0020
#define L2CAP_LM_SECURE 0x0020
/* L2CAP command codes */
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
#define L2CAP_COMMAND_REJ 0x01
#define L2CAP_CONN_REQ 0x02
#define L2CAP_CONN_REQ 0x02
#define L2CAP_CONN_RSP 0x03
#define L2CAP_CONN_RSP 0x03
#define L2CAP_CONF_REQ 0x04
#define L2CAP_CONF_REQ 0x04
#define L2CAP_CONF_RSP 0x05
#define L2CAP_CONF_RSP 0x05
#define L2CAP_DISCONN_REQ 0x06
#define L2CAP_DISCONN_REQ 0x06
#define L2CAP_DISCONN_RSP 0x07
#define L2CAP_DISCONN_RSP 0x07
#define L2CAP_ECHO_REQ 0x08
#define L2CAP_ECHO_REQ 0x08
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_ECHO_RSP 0x09
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_REQ 0x0a
#define L2CAP_INFO_RSP 0x0b
#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 */
/* L2CAP structures */
struct
l2cap_hdr
{
struct
l2cap_hdr
{
...
@@ -106,17 +123,23 @@ struct l2cap_conn_rsp {
...
@@ -106,17 +123,23 @@ struct l2cap_conn_rsp {
__le16
status
;
__le16
status
;
}
__attribute__
((
packed
));
}
__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 */
/* connect result */
#define L2CAP_CR_SUCCESS
0x0000
#define L2CAP_CR_SUCCESS
0x0000
#define L2CAP_CR_PEND
0x0001
#define L2CAP_CR_PEND
0x0001
#define L2CAP_CR_BAD_PSM
0x0002
#define L2CAP_CR_BAD_PSM
0x0002
#define L2CAP_CR_SEC_BLOCK
0x0003
#define L2CAP_CR_SEC_BLOCK
0x0003
#define L2CAP_CR_NO_MEM
0x0004
#define L2CAP_CR_NO_MEM
0x0004
/* connect status */
/* connect status */
#define L2CAP_CS_NO_INFO
0x0000
#define L2CAP_CS_NO_INFO
0x0000
#define L2CAP_CS_AUTHEN_PEND
0x0001
#define L2CAP_CS_AUTHEN_PEND
0x0001
#define L2CAP_CS_AUTHOR_PEND
0x0002
#define L2CAP_CS_AUTHOR_PEND
0x0002
struct
l2cap_conf_req
{
struct
l2cap_conf_req
{
__le16
dcid
;
__le16
dcid
;
...
@@ -143,10 +166,14 @@ struct l2cap_conf_opt {
...
@@ -143,10 +166,14 @@ struct l2cap_conf_opt {
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
#define L2CAP_CONF_OPT_SIZE 2
#define L2CAP_CONF_OPT_SIZE 2
#define L2CAP_CONF_HINT 0x80
#define L2CAP_CONF_MASK 0x7f
#define L2CAP_CONF_MTU 0x01
#define L2CAP_CONF_MTU 0x01
#define L2CAP_CONF_FLUSH_TO 0x02
#define L2CAP_CONF_FLUSH_TO 0x02
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_RFC 0x04
#define L2CAP_CONF_RFC 0x04
#define L2CAP_CONF_FCS 0x05
#define L2CAP_CONF_MAX_SIZE 22
#define L2CAP_CONF_MAX_SIZE 22
...
@@ -162,6 +189,8 @@ struct l2cap_conf_rfc {
...
@@ -162,6 +189,8 @@ struct l2cap_conf_rfc {
#define L2CAP_MODE_BASIC 0x00
#define L2CAP_MODE_BASIC 0x00
#define L2CAP_MODE_RETRANS 0x01
#define L2CAP_MODE_RETRANS 0x01
#define L2CAP_MODE_FLOWCTL 0x02
#define L2CAP_MODE_FLOWCTL 0x02
#define L2CAP_MODE_ERTM 0x03
#define L2CAP_MODE_STREAM 0x04
struct
l2cap_disconn_req
{
struct
l2cap_disconn_req
{
__le16
dcid
;
__le16
dcid
;
...
...
net/bluetooth/hci_core.c
View file @
bb400801
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/notifier.h>
#include <linux/rfkill.h>
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
...
@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
...
@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
hci_req_lock
(
hdev
);
hci_req_lock
(
hdev
);
if
(
hdev
->
rfkill
&&
rfkill_blocked
(
hdev
->
rfkill
))
{
ret
=
-
ERFKILL
;
goto
done
;
}
if
(
test_bit
(
HCI_UP
,
&
hdev
->
flags
))
{
if
(
test_bit
(
HCI_UP
,
&
hdev
->
flags
))
{
ret
=
-
EALREADY
;
ret
=
-
EALREADY
;
goto
done
;
goto
done
;
...
@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
...
@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
/* ---- Interface to HCI drivers ---- */
/* ---- 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 */
/* Alloc HCI device */
struct
hci_dev
*
hci_alloc_dev
(
void
)
struct
hci_dev
*
hci_alloc_dev
(
void
)
{
{
...
@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
struct
list_head
*
head
=
&
hci_dev_list
,
*
p
;
int
i
,
id
=
0
;
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
)
if
(
!
hdev
->
open
||
!
hdev
->
close
||
!
hdev
->
destruct
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
...
@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
hci_register_sysfs
(
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
);
hci_notify
(
hdev
,
HCI_DEV_REG
);
return
id
;
return
id
;
...
@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
...
@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
hci_notify
(
hdev
,
HCI_DEV_UNREG
);
if
(
hdev
->
rfkill
)
{
rfkill_unregister
(
hdev
->
rfkill
);
rfkill_destroy
(
hdev
->
rfkill
);
}
hci_unregister_sysfs
(
hdev
);
hci_unregister_sysfs
(
hdev
);
__hci_dev_put
(
hdev
);
__hci_dev_put
(
hdev
);
...
...
net/bluetooth/l2cap.c
View file @
bb400801
...
@@ -40,10 +40,10 @@
...
@@ -40,10 +40,10 @@
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <net/sock.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
...
@@ -52,7 +52,7 @@
...
@@ -52,7 +52,7 @@
#define VERSION "2.13"
#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
u8
l2cap_fixed_chan
[
8
]
=
{
0x02
,
};
static
const
struct
proto_ops
l2cap_sock_ops
;
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
...
@@ -134,7 +134,8 @@ static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16
struct
sock
*
s
;
struct
sock
*
s
;
read_lock
(
&
l
->
lock
);
read_lock
(
&
l
->
lock
);
s
=
__l2cap_get_chan_by_scid
(
l
,
cid
);
s
=
__l2cap_get_chan_by_scid
(
l
,
cid
);
if
(
s
)
bh_lock_sock
(
s
);
if
(
s
)
bh_lock_sock
(
s
);
read_unlock
(
&
l
->
lock
);
read_unlock
(
&
l
->
lock
);
return
s
;
return
s
;
}
}
...
@@ -154,17 +155,18 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8
...
@@ -154,17 +155,18 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8
struct
sock
*
s
;
struct
sock
*
s
;
read_lock
(
&
l
->
lock
);
read_lock
(
&
l
->
lock
);
s
=
__l2cap_get_chan_by_ident
(
l
,
ident
);
s
=
__l2cap_get_chan_by_ident
(
l
,
ident
);
if
(
s
)
bh_lock_sock
(
s
);
if
(
s
)
bh_lock_sock
(
s
);
read_unlock
(
&
l
->
lock
);
read_unlock
(
&
l
->
lock
);
return
s
;
return
s
;
}
}
static
u16
l2cap_alloc_cid
(
struct
l2cap_chan_list
*
l
)
static
u16
l2cap_alloc_cid
(
struct
l2cap_chan_list
*
l
)
{
{
u16
cid
=
0x0040
;
u16
cid
=
L2CAP_CID_DYN_START
;
for
(;
cid
<
0xffff
;
cid
++
)
{
for
(;
cid
<
L2CAP_CID_DYN_END
;
cid
++
)
{
if
(
!
__l2cap_get_chan_by_scid
(
l
,
cid
))
if
(
!
__l2cap_get_chan_by_scid
(
l
,
cid
))
return
cid
;
return
cid
;
}
}
...
@@ -204,7 +206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
...
@@ -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
;
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
;
conn
->
disc_reason
=
0x13
;
...
@@ -215,13 +218,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
...
@@ -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
);
l2cap_pi
(
sk
)
->
scid
=
l2cap_alloc_cid
(
l
);
}
else
if
(
sk
->
sk_type
==
SOCK_DGRAM
)
{
}
else
if
(
sk
->
sk_type
==
SOCK_DGRAM
)
{
/* Connectionless socket */
/* Connectionless socket */
l2cap_pi
(
sk
)
->
scid
=
0x0002
;
l2cap_pi
(
sk
)
->
scid
=
L2CAP_CID_CONN_LESS
;
l2cap_pi
(
sk
)
->
dcid
=
0x0002
;
l2cap_pi
(
sk
)
->
dcid
=
L2CAP_CID_CONN_LESS
;
l2cap_pi
(
sk
)
->
omtu
=
L2CAP_DEFAULT_MTU
;
l2cap_pi
(
sk
)
->
omtu
=
L2CAP_DEFAULT_MTU
;
}
else
{
}
else
{
/* Raw socket can send/recv signalling messages only */
/* Raw socket can send/recv signalling messages only */
l2cap_pi
(
sk
)
->
scid
=
0x0001
;
l2cap_pi
(
sk
)
->
scid
=
L2CAP_CID_SIGNALING
;
l2cap_pi
(
sk
)
->
dcid
=
0x0001
;
l2cap_pi
(
sk
)
->
dcid
=
L2CAP_CID_SIGNALING
;
l2cap_pi
(
sk
)
->
omtu
=
L2CAP_DEFAULT_MTU
;
l2cap_pi
(
sk
)
->
omtu
=
L2CAP_DEFAULT_MTU
;
}
}
...
@@ -272,7 +275,7 @@ static inline int l2cap_check_security(struct sock *sk)
...
@@ -272,7 +275,7 @@ static inline int l2cap_check_security(struct sock *sk)
if
(
l2cap_pi
(
sk
)
->
sec_level
==
BT_SECURITY_HIGH
)
if
(
l2cap_pi
(
sk
)
->
sec_level
==
BT_SECURITY_HIGH
)
auth_type
=
HCI_AT_NO_BONDING_MITM
;
auth_type
=
HCI_AT_NO_BONDING_MITM
;
else
else
auth_type
=
HCI_AT_NO_BONDING
;
auth_type
=
HCI_AT_NO_BONDING
;
if
(
l2cap_pi
(
sk
)
->
sec_level
==
BT_SECURITY_LOW
)
if
(
l2cap_pi
(
sk
)
->
sec_level
==
BT_SECURITY_LOW
)
l2cap_pi
(
sk
)
->
sec_level
=
BT_SECURITY_SDP
;
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
...
@@ -588,7 +591,8 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t
struct
sock
*
s
;
struct
sock
*
s
;
read_lock
(
&
l2cap_sk_list
.
lock
);
read_lock
(
&
l2cap_sk_list
.
lock
);
s
=
__l2cap_get_sock_by_psm
(
state
,
psm
,
src
);
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
);
read_unlock
(
&
l2cap_sk_list
.
lock
);
return
s
;
return
s
;
}
}
...
@@ -808,7 +812,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
...
@@ -808,7 +812,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
goto
done
;
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
))
{
!
capable
(
CAP_NET_BIND_SERVICE
))
{
err
=
-
EACCES
;
err
=
-
EACCES
;
goto
done
;
goto
done
;
...
@@ -825,7 +829,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
...
@@ -825,7 +829,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
l2cap_pi
(
sk
)
->
sport
=
la
.
l2_psm
;
l2cap_pi
(
sk
)
->
sport
=
la
.
l2_psm
;
sk
->
sk_state
=
BT_BOUND
;
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
;
l2cap_pi
(
sk
)
->
sec_level
=
BT_SECURITY_SDP
;
}
}
...
@@ -844,12 +849,13 @@ static int l2cap_do_connect(struct sock *sk)
...
@@ -844,12 +849,13 @@ static int l2cap_do_connect(struct sock *sk)
struct
hci_conn
*
hcon
;
struct
hci_conn
*
hcon
;
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
__u8
auth_type
;
__u8
auth_type
;
int
err
=
0
;
int
err
;
BT_DBG
(
"%s -> %s psm 0x%2.2x"
,
batostr
(
src
),
batostr
(
dst
),
BT_DBG
(
"%s -> %s psm 0x%2.2x"
,
batostr
(
src
),
batostr
(
dst
),
l2cap_pi
(
sk
)
->
psm
);
l2cap_pi
(
sk
)
->
psm
);
if
(
!
(
hdev
=
hci_get_route
(
dst
,
src
)))
hdev
=
hci_get_route
(
dst
,
src
);
if
(
!
hdev
)
return
-
EHOSTUNREACH
;
return
-
EHOSTUNREACH
;
hci_dev_lock_bh
(
hdev
);
hci_dev_lock_bh
(
hdev
);
...
@@ -950,7 +956,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
...
@@ -950,7 +956,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto
done
;
goto
done
;
}
}
switch
(
sk
->
sk_state
)
{
switch
(
sk
->
sk_state
)
{
case
BT_CONNECT
:
case
BT_CONNECT
:
case
BT_CONNECT2
:
case
BT_CONNECT2
:
case
BT_CONFIG
:
case
BT_CONFIG
:
...
@@ -975,7 +981,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
...
@@ -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
);
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
la
.
l2_bdaddr
);
l2cap_pi
(
sk
)
->
psm
=
la
.
l2_psm
;
l2cap_pi
(
sk
)
->
psm
=
la
.
l2_psm
;
if
((
err
=
l2cap_do_connect
(
sk
)))
err
=
l2cap_do_connect
(
sk
);
if
(
err
)
goto
done
;
goto
done
;
wait:
wait:
...
@@ -1009,9 +1016,9 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
...
@@ -1009,9 +1016,9 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
write_lock_bh
(
&
l2cap_sk_list
.
lock
);
write_lock_bh
(
&
l2cap_sk_list
.
lock
);
for
(
psm
=
0x1001
;
psm
<
0x1100
;
psm
+=
2
)
for
(
psm
=
0x1001
;
psm
<
0x1100
;
psm
+=
2
)
if
(
!
__l2cap_get_sock_by_addr
(
htobs
(
psm
),
src
))
{
if
(
!
__l2cap_get_sock_by_addr
(
cpu_to_le16
(
psm
),
src
))
{
l2cap_pi
(
sk
)
->
psm
=
htobs
(
psm
);
l2cap_pi
(
sk
)
->
psm
=
cpu_to_le16
(
psm
);
l2cap_pi
(
sk
)
->
sport
=
htobs
(
psm
);
l2cap_pi
(
sk
)
->
sport
=
cpu_to_le16
(
psm
);
err
=
0
;
err
=
0
;
break
;
break
;
}
}
...
@@ -1100,11 +1107,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
...
@@ -1100,11 +1107,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
if
(
peer
)
{
if
(
peer
)
{
la
->
l2_psm
=
l2cap_pi
(
sk
)
->
psm
;
la
->
l2_psm
=
l2cap_pi
(
sk
)
->
psm
;
bacpy
(
&
la
->
l2_bdaddr
,
&
bt_sk
(
sk
)
->
dst
);
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
{
}
else
{
la
->
l2_psm
=
l2cap_pi
(
sk
)
->
sport
;
la
->
l2_psm
=
l2cap_pi
(
sk
)
->
sport
;
bacpy
(
&
la
->
l2_bdaddr
,
&
bt_sk
(
sk
)
->
src
);
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
;
return
0
;
...
@@ -1114,7 +1121,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
...
@@ -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
l2cap_conn
*
conn
=
l2cap_pi
(
sk
)
->
conn
;
struct
sk_buff
*
skb
,
**
frag
;
struct
sk_buff
*
skb
,
**
frag
;
int
err
,
hlen
,
count
,
sent
=
0
;
int
err
,
hlen
,
count
,
sent
=
0
;
struct
l2cap_hdr
*
lh
;
struct
l2cap_hdr
*
lh
;
BT_DBG
(
"sk %p len %d"
,
sk
,
len
);
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)
...
@@ -1167,8 +1174,8 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
frag
=
&
(
*
frag
)
->
next
;
frag
=
&
(
*
frag
)
->
next
;
}
}
err
=
hci_send_acl
(
conn
->
hcon
,
skb
,
0
);
if
(
(
err
=
hci_send_acl
(
conn
->
hcon
,
skb
,
0
))
<
0
)
if
(
err
<
0
)
goto
fail
;
goto
fail
;
return
sent
;
return
sent
;
...
@@ -1556,7 +1563,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
...
@@ -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
l2cap_chan_list
*
l
=
&
conn
->
chan_list
;
struct
sk_buff
*
nskb
;
struct
sk_buff
*
nskb
;
struct
sock
*
sk
;
struct
sock
*
sk
;
BT_DBG
(
"conn %p"
,
conn
);
BT_DBG
(
"conn %p"
,
conn
);
...
@@ -1568,8 +1575,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
...
@@ -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 */
/* Don't send frame to the socket it came from */
if
(
skb
->
sk
==
sk
)
if
(
skb
->
sk
==
sk
)
continue
;
continue
;
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
!
(
nskb
=
skb_clone
(
skb
,
GFP_ATOMIC
))
)
if
(
!
nskb
)
continue
;
continue
;
if
(
sock_queue_rcv_skb
(
sk
,
nskb
))
if
(
sock_queue_rcv_skb
(
sk
,
nskb
))
...
@@ -1587,7 +1594,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
...
@@ -1587,7 +1594,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
struct
l2cap_hdr
*
lh
;
struct
l2cap_hdr
*
lh
;
int
len
,
count
;
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
;
len
=
L2CAP_HDR_SIZE
+
L2CAP_CMD_HDR_SIZE
+
dlen
;
count
=
min_t
(
unsigned
int
,
conn
->
mtu
,
len
);
count
=
min_t
(
unsigned
int
,
conn
->
mtu
,
len
);
...
@@ -1598,7 +1606,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
...
@@ -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
=
(
struct
l2cap_hdr
*
)
skb_put
(
skb
,
L2CAP_HDR_SIZE
);
lh
->
len
=
cpu_to_le16
(
L2CAP_CMD_HDR_SIZE
+
dlen
);
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
=
(
struct
l2cap_cmd_hdr
*
)
skb_put
(
skb
,
L2CAP_CMD_HDR_SIZE
);
cmd
->
code
=
code
;
cmd
->
code
=
code
;
...
@@ -1739,8 +1747,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
...
@@ -1739,8 +1747,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
while
(
len
>=
L2CAP_CONF_OPT_SIZE
)
{
while
(
len
>=
L2CAP_CONF_OPT_SIZE
)
{
len
-=
l2cap_get_conf_opt
(
&
req
,
&
type
,
&
olen
,
&
val
);
len
-=
l2cap_get_conf_opt
(
&
req
,
&
type
,
&
olen
,
&
val
);
hint
=
type
&
0x80
;
hint
=
type
&
L2CAP_CONF_HINT
;
type
&=
0x7f
;
type
&=
L2CAP_CONF_MASK
;
switch
(
type
)
{
switch
(
type
)
{
case
L2CAP_CONF_MTU
:
case
L2CAP_CONF_MTU
:
...
@@ -1966,10 +1974,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
...
@@ -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
);
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
(
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
;
return
0
;
}
else
{
}
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
;
return
0
;
}
}
...
@@ -2012,7 +2022,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
...
@@ -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
);
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
;
return
-
ENOENT
;
if
(
sk
->
sk_state
==
BT_DISCONN
)
if
(
sk
->
sk_state
==
BT_DISCONN
)
...
@@ -2079,9 +2090,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
...
@@ -2079,9 +2090,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
flags
=
__le16_to_cpu
(
rsp
->
flags
);
flags
=
__le16_to_cpu
(
rsp
->
flags
);
result
=
__le16_to_cpu
(
rsp
->
result
);
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
;
return
0
;
switch
(
result
)
{
switch
(
result
)
{
...
@@ -2142,7 +2155,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
...
@@ -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
);
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
;
return
0
;
rsp
.
dcid
=
cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
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
...
@@ -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
);
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
;
return
0
;
l2cap_chan_del
(
sk
,
0
);
l2cap_chan_del
(
sk
,
0
);
...
@@ -2230,7 +2245,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
...
@@ -2230,7 +2245,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
if
(
type
==
L2CAP_IT_FEAT_MASK
)
{
if
(
type
==
L2CAP_IT_FEAT_MASK
)
{
conn
->
feat_mask
=
get_unaligned_le32
(
rsp
->
data
);
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
;
struct
l2cap_info_req
req
;
req
.
type
=
cpu_to_le16
(
L2CAP_IT_FIXED_CHAN
);
req
.
type
=
cpu_to_le16
(
L2CAP_IT_FIXED_CHAN
);
...
@@ -2403,7 +2418,8 @@ drop:
...
@@ -2403,7 +2418,8 @@ drop:
kfree_skb
(
skb
);
kfree_skb
(
skb
);
done:
done:
if
(
sk
)
bh_unlock_sock
(
sk
);
if
(
sk
)
bh_unlock_sock
(
sk
);
return
0
;
return
0
;
}
}
...
@@ -2420,11 +2436,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
...
@@ -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
);
BT_DBG
(
"len %d, cid 0x%4.4x"
,
len
,
cid
);
switch
(
cid
)
{
switch
(
cid
)
{
case
0x0001
:
case
L2CAP_CID_SIGNALING
:
l2cap_sig_channel
(
conn
,
skb
);
l2cap_sig_channel
(
conn
,
skb
);
break
;
break
;
case
0x0002
:
case
L2CAP_CID_CONN_LESS
:
psm
=
get_unaligned
((
__le16
*
)
skb
->
data
);
psm
=
get_unaligned
((
__le16
*
)
skb
->
data
);
skb_pull
(
skb
,
2
);
skb_pull
(
skb
,
2
);
l2cap_conless_channel
(
conn
,
psm
,
skb
);
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
...
@@ -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) */
/* 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
;
goto
drop
;
skb_copy_from_linear_data
(
skb
,
skb_put
(
conn
->
rx_skb
,
skb
->
len
),
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)
...
@@ -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
"
,
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
),
batostr
(
&
bt_sk
(
sk
)
->
src
),
batostr
(
&
bt_sk
(
sk
)
->
dst
),
sk
->
sk_state
,
btohs
(
pi
->
psm
),
pi
->
scid
,
pi
->
d
cid
,
sk
->
sk_state
,
__le16_to_cpu
(
pi
->
psm
),
pi
->
s
cid
,
pi
->
imtu
,
pi
->
omtu
,
pi
->
sec_level
);
pi
->
dcid
,
pi
->
imtu
,
pi
->
omtu
,
pi
->
sec_level
);
}
}
read_unlock_bh
(
&
l2cap_sk_list
.
lock
);
read_unlock_bh
(
&
l2cap_sk_list
.
lock
);
return
(
str
-
buf
)
;
return
str
-
buf
;
}
}
static
CLASS_ATTR
(
l2cap
,
S_IRUGO
,
l2cap_sysfs_show
,
NULL
);
static
CLASS_ATTR
(
l2cap
,
S_IRUGO
,
l2cap_sysfs_show
,
NULL
);
...
...
net/bluetooth/rfcomm/core.c
View file @
bb400801
...
@@ -679,7 +679,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
...
@@ -679,7 +679,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
bacpy
(
&
addr
.
l2_bdaddr
,
dst
);
bacpy
(
&
addr
.
l2_bdaddr
,
dst
);
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_psm
=
htobs
(
RFCOMM_PSM
);
addr
.
l2_psm
=
cpu_to_le16
(
RFCOMM_PSM
);
addr
.
l2_cid
=
0
;
addr
.
l2_cid
=
0
;
*
err
=
kernel_connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
),
O_NONBLOCK
);
*
err
=
kernel_connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
),
O_NONBLOCK
);
if
(
*
err
==
0
||
*
err
==
-
EINPROGRESS
)
if
(
*
err
==
0
||
*
err
==
-
EINPROGRESS
)
...
@@ -852,9 +852,9 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
...
@@ -852,9 +852,9 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
}
}
if
(
cr
&&
channel_mtu
>=
0
)
if
(
cr
&&
channel_mtu
>=
0
)
pn
->
mtu
=
htobs
(
channel_mtu
);
pn
->
mtu
=
cpu_to_le16
(
channel_mtu
);
else
else
pn
->
mtu
=
htobs
(
d
->
mtu
);
pn
->
mtu
=
cpu_to_le16
(
d
->
mtu
);
*
ptr
=
__fcs
(
buf
);
ptr
++
;
*
ptr
=
__fcs
(
buf
);
ptr
++
;
...
@@ -1056,7 +1056,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
...
@@ -1056,7 +1056,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
if
(
len
>
127
)
{
if
(
len
>
127
)
{
hdr
=
(
void
*
)
skb_push
(
skb
,
4
);
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
{
}
else
{
hdr
=
(
void
*
)
skb_push
(
skb
,
3
);
hdr
=
(
void
*
)
skb_push
(
skb
,
3
);
hdr
->
len
=
__len8
(
len
);
hdr
->
len
=
__len8
(
len
);
...
@@ -1289,7 +1289,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
...
@@ -1289,7 +1289,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
d
->
priority
=
pn
->
priority
;
d
->
priority
=
pn
->
priority
;
d
->
mtu
=
btohs
(
pn
->
mtu
);
d
->
mtu
=
__le16_to_cpu
(
pn
->
mtu
);
if
(
cr
&&
d
->
mtu
>
s
->
mtu
)
if
(
cr
&&
d
->
mtu
>
s
->
mtu
)
d
->
mtu
=
s
->
mtu
;
d
->
mtu
=
s
->
mtu
;
...
@@ -1922,7 +1922,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
...
@@ -1922,7 +1922,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
/* Bind socket */
/* Bind socket */
bacpy
(
&
addr
.
l2_bdaddr
,
ba
);
bacpy
(
&
addr
.
l2_bdaddr
,
ba
);
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_psm
=
htobs
(
RFCOMM_PSM
);
addr
.
l2_psm
=
cpu_to_le16
(
RFCOMM_PSM
);
addr
.
l2_cid
=
0
;
addr
.
l2_cid
=
0
;
err
=
kernel_bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
err
=
kernel_bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
if
(
err
<
0
)
{
if
(
err
<
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment