Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
407d819c
Commit
407d819c
authored
Jul 19, 2008
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-2.6
parents
7abbcd6a
b1235d79
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1112 additions
and
271 deletions
+1112
-271
fs/compat_ioctl.c
fs/compat_ioctl.c
+1
-0
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+1
-0
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+64
-4
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+13
-6
include/net/bluetooth/rfcomm.h
include/net/bluetooth/rfcomm.h
+2
-0
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+52
-1
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+5
-0
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+76
-20
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+29
-13
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+454
-58
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+5
-13
net/bluetooth/hci_sysfs.c
net/bluetooth/hci_sysfs.c
+21
-10
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+10
-0
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+234
-103
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+60
-32
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+16
-7
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+58
-1
net/bluetooth/sco.c
net/bluetooth/sco.c
+11
-3
No files found.
fs/compat_ioctl.c
View file @
407d819c
...
...
@@ -2346,6 +2346,7 @@ COMPATIBLE_IOCTL(HCIGETDEVLIST)
COMPATIBLE_IOCTL
(
HCIGETDEVINFO
)
COMPATIBLE_IOCTL
(
HCIGETCONNLIST
)
COMPATIBLE_IOCTL
(
HCIGETCONNINFO
)
COMPATIBLE_IOCTL
(
HCIGETAUTHINFO
)
COMPATIBLE_IOCTL
(
HCISETRAW
)
COMPATIBLE_IOCTL
(
HCISETSCAN
)
COMPATIBLE_IOCTL
(
HCISETAUTH
)
...
...
include/net/bluetooth/bluetooth.h
View file @
407d819c
...
...
@@ -121,6 +121,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void
bt_sock_unlink
(
struct
bt_sock_list
*
l
,
struct
sock
*
s
);
int
bt_sock_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
struct
msghdr
*
msg
,
size_t
len
,
int
flags
);
uint
bt_sock_poll
(
struct
file
*
file
,
struct
socket
*
sock
,
poll_table
*
wait
);
int
bt_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
);
int
bt_sock_wait_state
(
struct
sock
*
sk
,
int
state
,
unsigned
long
timeo
);
void
bt_accept_enqueue
(
struct
sock
*
parent
,
struct
sock
*
sk
);
...
...
include/net/bluetooth/hci.h
View file @
407d819c
...
...
@@ -72,8 +72,6 @@ enum {
HCI_INQUIRY
,
HCI_RAW
,
HCI_SECMGR
};
/* HCI ioctl defines */
...
...
@@ -86,6 +84,7 @@ enum {
#define HCIGETDEVINFO _IOR('H', 211, int)
#define HCIGETCONNLIST _IOR('H', 212, int)
#define HCIGETCONNINFO _IOR('H', 213, int)
#define HCIGETAUTHINFO _IOR('H', 215, int)
#define HCISETRAW _IOW('H', 220, int)
#define HCISETSCAN _IOW('H', 221, int)
...
...
@@ -97,8 +96,6 @@ enum {
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETSECMGR _IOW('H', 230, int)
#define HCIINQUIRY _IOR('H', 240, int)
/* HCI timeouts */
...
...
@@ -137,6 +134,8 @@ enum {
#define ESCO_EV4 0x0010
#define ESCO_EV5 0x0020
#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
/* ACL flags */
#define ACL_CONT 0x01
#define ACL_START 0x02
...
...
@@ -178,6 +177,8 @@ enum {
#define LMP_SNIFF_SUBR 0x02
#define LMP_SIMPLE_PAIR 0x08
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
#define HCI_CM_HOLD 0x0001
...
...
@@ -199,6 +200,14 @@ enum {
#define HCI_LM_RELIABLE 0x0010
#define HCI_LM_SECURE 0x0020
/* Authentication types */
#define HCI_AT_NO_BONDING 0x00
#define HCI_AT_NO_BONDING_MITM 0x01
#define HCI_AT_DEDICATED_BONDING 0x02
#define HCI_AT_DEDICATED_BONDING_MITM 0x03
#define HCI_AT_GENERAL_BONDING 0x04
#define HCI_AT_GENERAL_BONDING_MITM 0x05
/* ----- HCI Commands ---- */
#define HCI_OP_INQUIRY 0x0401
struct
hci_cp_inquiry
{
...
...
@@ -402,6 +411,17 @@ struct hci_rp_write_link_policy {
__le16
handle
;
}
__attribute__
((
packed
));
#define HCI_OP_READ_DEF_LINK_POLICY 0x080e
struct
hci_rp_read_def_link_policy
{
__u8
status
;
__le16
policy
;
}
__attribute__
((
packed
));
#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f
struct
hci_cp_write_def_link_policy
{
__le16
policy
;
}
__attribute__
((
packed
));
#define HCI_OP_SNIFF_SUBRATE 0x0811
struct
hci_cp_sniff_subrate
{
__le16
handle
;
...
...
@@ -501,6 +521,17 @@ struct hci_cp_host_buffer_size {
__le16
sco_max_pkt
;
}
__attribute__
((
packed
));
#define HCI_OP_READ_SSP_MODE 0x0c55
struct
hci_rp_read_ssp_mode
{
__u8
status
;
__u8
mode
;
}
__attribute__
((
packed
));
#define HCI_OP_WRITE_SSP_MODE 0x0c56
struct
hci_cp_write_ssp_mode
{
__u8
mode
;
}
__attribute__
((
packed
));
#define HCI_OP_READ_LOCAL_VERSION 0x1001
struct
hci_rp_read_local_version
{
__u8
status
;
...
...
@@ -696,6 +727,13 @@ struct hci_ev_clock_offset {
__le16
clock_offset
;
}
__attribute__
((
packed
));
#define HCI_EV_PKT_TYPE_CHANGE 0x1d
struct
hci_ev_pkt_type_change
{
__u8
status
;
__le16
handle
;
__le16
pkt_type
;
}
__attribute__
((
packed
));
#define HCI_EV_PSCAN_REP_MODE 0x20
struct
hci_ev_pscan_rep_mode
{
bdaddr_t
bdaddr
;
...
...
@@ -774,6 +812,23 @@ struct extended_inquiry_info {
__u8
data
[
240
];
}
__attribute__
((
packed
));
#define HCI_EV_IO_CAPA_REQUEST 0x31
struct
hci_ev_io_capa_request
{
bdaddr_t
bdaddr
;
}
__attribute__
((
packed
));
#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct
hci_ev_simple_pair_complete
{
__u8
status
;
bdaddr_t
bdaddr
;
}
__attribute__
((
packed
));
#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
struct
hci_ev_remote_host_features
{
bdaddr_t
bdaddr
;
__u8
features
[
8
];
}
__attribute__
((
packed
));
/* Internal events generated by Bluetooth stack */
#define HCI_EV_STACK_INTERNAL 0xfd
struct
hci_ev_stack_internal
{
...
...
@@ -951,6 +1006,11 @@ struct hci_conn_info_req {
struct
hci_conn_info
conn_info
[
0
];
};
struct
hci_auth_info_req
{
bdaddr_t
bdaddr
;
__u8
type
;
};
struct
hci_inquiry_req
{
__u16
dev_id
;
__u16
flags
;
...
...
include/net/bluetooth/hci_core.h
View file @
407d819c
...
...
@@ -40,6 +40,7 @@ struct inquiry_data {
__u8
dev_class
[
3
];
__le16
clock_offset
;
__s8
rssi
;
__u8
ssp_mode
;
};
struct
inquiry_entry
{
...
...
@@ -75,6 +76,7 @@ struct hci_dev {
__u8
dev_class
[
3
];
__u8
features
[
8
];
__u8
commands
[
64
];
__u8
ssp_mode
;
__u8
hci_ver
;
__u16
hci_rev
;
__u16
manufacturer
;
...
...
@@ -161,9 +163,12 @@ struct hci_conn {
__u8
attempt
;
__u8
dev_class
[
3
];
__u8
features
[
8
];
__u8
ssp_mode
;
__u16
interval
;
__u16
pkt_type
;
__u16
link_policy
;
__u32
link_mode
;
__u8
auth_type
;
__u8
power_save
;
unsigned
long
pend
;
...
...
@@ -344,7 +349,7 @@ static inline void hci_conn_put(struct hci_conn *conn)
if
(
conn
->
state
==
BT_CONNECTED
)
{
timeo
=
msecs_to_jiffies
(
HCI_DISCONN_TIMEOUT
);
if
(
!
conn
->
out
)
timeo
*=
2
;
timeo
*=
5
;
}
else
timeo
=
msecs_to_jiffies
(
10
);
}
else
...
...
@@ -418,6 +423,7 @@ int hci_get_dev_list(void __user *arg);
int
hci_get_dev_info
(
void
__user
*
arg
);
int
hci_get_conn_list
(
void
__user
*
arg
);
int
hci_get_conn_info
(
struct
hci_dev
*
hdev
,
void
__user
*
arg
);
int
hci_get_auth_info
(
struct
hci_dev
*
hdev
,
void
__user
*
arg
);
int
hci_inquiry
(
void
__user
*
arg
);
void
hci_event_packet
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
);
...
...
@@ -459,6 +465,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF)
#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
/* ----- HCI protocols ----- */
struct
hci_proto
{
...
...
@@ -474,7 +481,7 @@ struct hci_proto {
int
(
*
recv_acldata
)
(
struct
hci_conn
*
conn
,
struct
sk_buff
*
skb
,
__u16
flags
);
int
(
*
recv_scodata
)
(
struct
hci_conn
*
conn
,
struct
sk_buff
*
skb
);
int
(
*
auth_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
);
int
(
*
encrypt_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
);
int
(
*
encrypt_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
encrypt
);
};
static
inline
int
hci_proto_connect_ind
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
__u8
type
)
...
...
@@ -532,17 +539,17 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
hp
->
auth_cfm
(
conn
,
status
);
}
static
inline
void
hci_proto_encrypt_cfm
(
struct
hci_conn
*
conn
,
__u8
status
)
static
inline
void
hci_proto_encrypt_cfm
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
encrypt
)
{
register
struct
hci_proto
*
hp
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
encrypt_cfm
)
hp
->
encrypt_cfm
(
conn
,
status
);
hp
->
encrypt_cfm
(
conn
,
status
,
encrypt
);
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
encrypt_cfm
)
hp
->
encrypt_cfm
(
conn
,
status
);
hp
->
encrypt_cfm
(
conn
,
status
,
encrypt
);
}
int
hci_register_proto
(
struct
hci_proto
*
hproto
);
...
...
@@ -579,7 +586,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
{
struct
list_head
*
p
;
hci_proto_encrypt_cfm
(
conn
,
status
);
hci_proto_encrypt_cfm
(
conn
,
status
,
encrypt
);
read_lock_bh
(
&
hci_cb_list_lock
);
list_for_each
(
p
,
&
hci_cb_list
)
{
...
...
include/net/bluetooth/rfcomm.h
View file @
407d819c
...
...
@@ -180,7 +180,9 @@ struct rfcomm_dlc {
u8
addr
;
u8
priority
;
u8
v24_sig
;
u8
remote_v24_sig
;
u8
mscex
;
u8
out
;
u32
link_mode
;
...
...
net/bluetooth/af_bluetooth.c
View file @
407d819c
...
...
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <net/sock.h>
#include <asm/ioctls.h>
#if defined(CONFIG_KMOD)
#include <linux/kmod.h>
...
...
@@ -48,7 +49,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "2.1
1
"
#define VERSION "2.1
2
"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
...
...
@@ -266,6 +267,8 @@ 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
)
sock_recv_timestamp
(
msg
,
sk
,
skb
);
skb_free_datagram
(
sk
,
skb
);
...
...
@@ -329,6 +332,54 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
}
EXPORT_SYMBOL
(
bt_sock_poll
);
int
bt_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sk_buff
*
skb
;
long
amount
;
int
err
;
BT_DBG
(
"sk %p cmd %x arg %lx"
,
sk
,
cmd
,
arg
);
switch
(
cmd
)
{
case
TIOCOUTQ
:
if
(
sk
->
sk_state
==
BT_LISTEN
)
return
-
EINVAL
;
amount
=
sk
->
sk_sndbuf
-
atomic_read
(
&
sk
->
sk_wmem_alloc
);
if
(
amount
<
0
)
amount
=
0
;
err
=
put_user
(
amount
,
(
int
__user
*
)
arg
);
break
;
case
TIOCINQ
:
if
(
sk
->
sk_state
==
BT_LISTEN
)
return
-
EINVAL
;
lock_sock
(
sk
);
skb
=
skb_peek
(
&
sk
->
sk_receive_queue
);
amount
=
skb
?
skb
->
len
:
0
;
release_sock
(
sk
);
err
=
put_user
(
amount
,
(
int
__user
*
)
arg
);
break
;
case
SIOCGSTAMP
:
err
=
sock_get_timestamp
(
sk
,
(
struct
timeval
__user
*
)
arg
);
break
;
case
SIOCGSTAMPNS
:
err
=
sock_get_timestampns
(
sk
,
(
struct
timespec
__user
*
)
arg
);
break
;
default:
err
=
-
ENOIOCTLCMD
;
break
;
}
return
err
;
}
EXPORT_SYMBOL
(
bt_sock_ioctl
);
int
bt_sock_wait_state
(
struct
sock
*
sk
,
int
state
,
unsigned
long
timeo
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
...
...
net/bluetooth/bnep/core.c
View file @
407d819c
...
...
@@ -503,6 +503,11 @@ static int bnep_session(void *arg)
/* Delete network device */
unregister_netdev
(
dev
);
/* Wakeup user-space polling for socket errors */
s
->
sock
->
sk
->
sk_err
=
EUNATCH
;
wake_up_interruptible
(
s
->
sock
->
sk
->
sk_sleep
);
/* Release the socket */
fput
(
s
->
sock
->
file
);
...
...
net/bluetooth/hci_conn.c
View file @
407d819c
...
...
@@ -59,24 +59,31 @@ void hci_acl_connect(struct hci_conn *conn)
BT_DBG
(
"%p"
,
conn
);
conn
->
state
=
BT_CONNECT
;
conn
->
out
=
1
;
conn
->
out
=
1
;
conn
->
link_mode
=
HCI_LM_MASTER
;
conn
->
attempt
++
;
conn
->
link_policy
=
hdev
->
link_policy
;
memset
(
&
cp
,
0
,
sizeof
(
cp
));
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
cp
.
pscan_rep_mode
=
0x02
;
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
))
&&
inquiry_entry_age
(
ie
)
<=
INQUIRY_ENTRY_AGE_MAX
)
{
cp
.
pscan_rep_mode
=
ie
->
data
.
pscan_rep_mode
;
cp
.
pscan_mode
=
ie
->
data
.
pscan_mode
;
cp
.
clock_offset
=
ie
->
data
.
clock_offset
|
cpu_to_le16
(
0x8000
);
if
((
ie
=
hci_inquiry_cache_lookup
(
hdev
,
&
conn
->
dst
)))
{
if
(
inquiry_entry_age
(
ie
)
<=
INQUIRY_ENTRY_AGE_MAX
)
{
cp
.
pscan_rep_mode
=
ie
->
data
.
pscan_rep_mode
;
cp
.
pscan_mode
=
ie
->
data
.
pscan_mode
;
cp
.
clock_offset
=
ie
->
data
.
clock_offset
|
cpu_to_le16
(
0x8000
);
}
memcpy
(
conn
->
dev_class
,
ie
->
data
.
dev_class
,
3
);
conn
->
ssp_mode
=
ie
->
data
.
ssp_mode
;
}
cp
.
pkt_type
=
cpu_to_le16
(
hdev
->
pkt_type
&
ACL_PTYPE_MASK
);
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt_type
);
if
(
lmp_rswitch_capable
(
hdev
)
&&
!
(
hdev
->
link_mode
&
HCI_LM_MASTER
))
cp
.
role_switch
=
0x01
;
else
...
...
@@ -122,7 +129,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
conn
->
out
=
1
;
cp
.
handle
=
cpu_to_le16
(
handle
);
cp
.
pkt_type
=
cpu_to_le16
(
hdev
->
pkt_type
&
SCO_PTYPE_MASK
);
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt_type
);
hci_send_cmd
(
hdev
,
HCI_OP_ADD_SCO
,
sizeof
(
cp
),
&
cp
);
}
...
...
@@ -138,7 +145,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
conn
->
out
=
1
;
cp
.
handle
=
cpu_to_le16
(
handle
);
cp
.
pkt_type
=
cpu_to_le16
(
hdev
->
esco
_type
);
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt
_type
);
cp
.
tx_bandwidth
=
cpu_to_le32
(
0x00001f40
);
cp
.
rx_bandwidth
=
cpu_to_le32
(
0x00001f40
);
...
...
@@ -163,11 +170,13 @@ static void hci_conn_timeout(unsigned long arg)
switch
(
conn
->
state
)
{
case
BT_CONNECT
:
case
BT_CONNECT2
:
if
(
conn
->
type
==
ACL_LINK
)
hci_acl_connect_cancel
(
conn
);
else
hci_acl_disconn
(
conn
,
0x13
);
break
;
case
BT_CONFIG
:
case
BT_CONNECTED
:
hci_acl_disconn
(
conn
,
0x13
);
break
;
...
...
@@ -199,13 +208,28 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
return
NULL
;
bacpy
(
&
conn
->
dst
,
dst
);
conn
->
hdev
=
hdev
;
conn
->
type
=
type
;
conn
->
mode
=
HCI_CM_ACTIVE
;
conn
->
state
=
BT_OPEN
;
conn
->
hdev
=
hdev
;
conn
->
type
=
type
;
conn
->
mode
=
HCI_CM_ACTIVE
;
conn
->
state
=
BT_OPEN
;
conn
->
power_save
=
1
;
switch
(
type
)
{
case
ACL_LINK
:
conn
->
pkt_type
=
hdev
->
pkt_type
&
ACL_PTYPE_MASK
;
break
;
case
SCO_LINK
:
if
(
lmp_esco_capable
(
hdev
))
conn
->
pkt_type
=
hdev
->
esco_type
&
SCO_ESCO_MASK
;
else
conn
->
pkt_type
=
hdev
->
pkt_type
&
SCO_PTYPE_MASK
;
break
;
case
ESCO_LINK
:
conn
->
pkt_type
=
hdev
->
esco_type
;
break
;
}
skb_queue_head_init
(
&
conn
->
data_q
);
setup_timer
(
&
conn
->
disc_timer
,
hci_conn_timeout
,
(
unsigned
long
)
conn
);
...
...
@@ -221,8 +245,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
if
(
hdev
->
notify
)
hdev
->
notify
(
hdev
,
HCI_NOTIFY_CONN_ADD
);
hci_conn_add_sysfs
(
conn
);
tasklet_enable
(
&
hdev
->
tx_task
);
return
conn
;
...
...
@@ -254,12 +276,14 @@ int hci_conn_del(struct hci_conn *conn)
}
tasklet_disable
(
&
hdev
->
tx_task
);
hci_conn_hash_del
(
hdev
,
conn
);
if
(
hdev
->
notify
)
hdev
->
notify
(
hdev
,
HCI_NOTIFY_CONN_DEL
);
tasklet_enable
(
&
hdev
->
tx_task
);
skb_queue_purge
(
&
conn
->
data_q
);
hci_conn_del_sysfs
(
conn
);
return
0
;
}
...
...
@@ -355,13 +379,21 @@ int hci_conn_auth(struct hci_conn *conn)
{
BT_DBG
(
"conn %p"
,
conn
);
if
(
conn
->
ssp_mode
>
0
&&
conn
->
hdev
->
ssp_mode
>
0
)
{
if
(
!
(
conn
->
auth_type
&
0x01
))
{
conn
->
auth_type
=
HCI_AT_GENERAL_BONDING_MITM
;
conn
->
link_mode
&=
~
HCI_LM_AUTH
;
}
}
if
(
conn
->
link_mode
&
HCI_LM_AUTH
)
return
1
;
if
(
!
test_and_set_bit
(
HCI_CONN_AUTH_PEND
,
&
conn
->
pend
))
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
cpu_to_le16
(
conn
->
handle
);
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
return
0
;
}
...
...
@@ -373,7 +405,7 @@ int hci_conn_encrypt(struct hci_conn *conn)
BT_DBG
(
"conn %p"
,
conn
);
if
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
return
1
;
return
hci_conn_auth
(
conn
)
;
if
(
test_and_set_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
return
0
;
...
...
@@ -382,7 +414,8 @@ int hci_conn_encrypt(struct hci_conn *conn)
struct
hci_cp_set_conn_encrypt
cp
;
cp
.
handle
=
cpu_to_le16
(
conn
->
handle
);
cp
.
encrypt
=
1
;
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_SET_CONN_ENCRYPT
,
sizeof
(
cp
),
&
cp
);
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_SET_CONN_ENCRYPT
,
sizeof
(
cp
),
&
cp
);
}
return
0
;
}
...
...
@@ -396,7 +429,8 @@ int hci_conn_change_link_key(struct hci_conn *conn)
if
(
!
test_and_set_bit
(
HCI_CONN_AUTH_PEND
,
&
conn
->
pend
))
{
struct
hci_cp_change_conn_link_key
cp
;
cp
.
handle
=
cpu_to_le16
(
conn
->
handle
);
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_CHANGE_CONN_LINK_KEY
,
sizeof
(
cp
),
&
cp
);
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_CHANGE_CONN_LINK_KEY
,
sizeof
(
cp
),
&
cp
);
}
return
0
;
}
...
...
@@ -498,6 +532,8 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
c
->
state
=
BT_CLOSED
;
hci_conn_del_sysfs
(
c
);
hci_proto_disconn_ind
(
c
,
0x16
);
hci_conn_del
(
c
);
}
...
...
@@ -600,3 +636,23 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
return
copy_to_user
(
ptr
,
&
ci
,
sizeof
(
ci
))
?
-
EFAULT
:
0
;
}
int
hci_get_auth_info
(
struct
hci_dev
*
hdev
,
void
__user
*
arg
)
{
struct
hci_auth_info_req
req
;
struct
hci_conn
*
conn
;
if
(
copy_from_user
(
&
req
,
arg
,
sizeof
(
req
)))
return
-
EFAULT
;
hci_dev_lock_bh
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
req
.
bdaddr
);
if
(
conn
)
req
.
type
=
conn
->
auth_type
;
hci_dev_unlock_bh
(
hdev
);
if
(
!
conn
)
return
-
ENOENT
;
return
copy_to_user
(
arg
,
&
req
,
sizeof
(
req
))
?
-
EFAULT
:
0
;
}
net/bluetooth/hci_core.c
View file @
407d819c
...
...
@@ -279,10 +279,20 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG
(
"%s %x"
,
hdev
->
name
,
encrypt
);
/*
Authentica
tion */
/*
Encryp
tion */
hci_send_cmd
(
hdev
,
HCI_OP_WRITE_ENCRYPT_MODE
,
1
,
&
encrypt
);
}
static
void
hci_linkpol_req
(
struct
hci_dev
*
hdev
,
unsigned
long
opt
)
{
__le16
policy
=
cpu_to_le16
(
opt
);
BT_DBG
(
"%s %x"
,
hdev
->
name
,
opt
);
/* Default link policy */
hci_send_cmd
(
hdev
,
HCI_OP_WRITE_DEF_LINK_POLICY
,
2
,
&
policy
);
}
/* Get HCI device by index.
* Device is held on return. */
struct
hci_dev
*
hci_dev_get
(
int
index
)
...
...
@@ -694,32 +704,35 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
msecs_to_jiffies
(
HCI_INIT_TIMEOUT
));
break
;
case
HCISETPTYPE
:
hdev
->
pkt_type
=
(
__u16
)
dr
.
dev_opt
;
break
;
case
HCISETLINKPOL
:
hdev
->
link_policy
=
(
__u16
)
dr
.
dev_opt
;
err
=
hci_request
(
hdev
,
hci_linkpol_req
,
dr
.
dev_opt
,
msecs_to_jiffies
(
HCI_INIT_TIMEOUT
));
break
;
case
HCISETLINKMODE
:
hdev
->
link_mode
=
((
__u16
)
dr
.
dev_opt
)
&
(
HCI_LM_MASTER
|
HCI_LM_ACCEPT
);
hdev
->
link_mode
=
((
__u16
)
dr
.
dev_opt
)
&
(
HCI_LM_MASTER
|
HCI_LM_ACCEPT
);
break
;
case
HCISETPTYPE
:
hdev
->
pkt_type
=
(
__u16
)
dr
.
dev_opt
;
break
;
case
HCISETACLMTU
:
hdev
->
acl_mtu
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
1
);
hdev
->
acl_pkts
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
0
);
hdev
->
acl_mtu
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
1
);
hdev
->
acl_pkts
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
0
);
break
;
case
HCISETSCOMTU
:
hdev
->
sco_mtu
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
1
);
hdev
->
sco_pkts
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
0
);
hdev
->
sco_mtu
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
1
);
hdev
->
sco_pkts
=
*
((
__u16
*
)
&
dr
.
dev_opt
+
0
);
break
;
default:
err
=
-
EINVAL
;
break
;
}
hci_dev_put
(
hdev
);
return
err
;
}
...
...
@@ -1270,9 +1283,12 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
struct
hci_conn
*
c
;
c
=
list_entry
(
p
,
struct
hci_conn
,
list
);
if
(
c
->
type
!=
type
||
c
->
state
!=
BT_CONNECTED
||
skb_queue_empty
(
&
c
->
data_q
))
if
(
c
->
type
!=
type
||
skb_queue_empty
(
&
c
->
data_q
))
continue
;
if
(
c
->
state
!=
BT_CONNECTED
&&
c
->
state
!=
BT_CONFIG
)
continue
;
num
++
;
if
(
c
->
sent
<
min
)
{
...
...
net/bluetooth/hci_event.c
View file @
407d819c
This diff is collapsed.
Click to expand it.
net/bluetooth/hci_sock.c
View file @
407d819c
...
...
@@ -193,19 +193,11 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
return
0
;
case
HCISETSECMGR
:
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EACCES
;
if
(
arg
)
set_bit
(
HCI_SECMGR
,
&
hdev
->
flags
);
else
clear_bit
(
HCI_SECMGR
,
&
hdev
->
flags
);
return
0
;
case
HCIGETCONNINFO
:
return
hci_get_conn_info
(
hdev
,
(
void
__user
*
)
arg
);
return
hci_get_conn_info
(
hdev
,
(
void
__user
*
)
arg
);
case
HCIGETAUTHINFO
:
return
hci_get_auth_info
(
hdev
,
(
void
__user
*
)
arg
);
default:
if
(
hdev
->
ioctl
)
...
...
@@ -217,7 +209,7 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
static
int
hci_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
sock
*
sk
=
sock
->
sk
;
void
__user
*
argp
=
(
void
__user
*
)
arg
;
void
__user
*
argp
=
(
void
__user
*
)
arg
;
int
err
;
BT_DBG
(
"cmd %x arg %lx"
,
cmd
,
arg
);
...
...
net/bluetooth/hci_sysfs.c
View file @
407d819c
...
...
@@ -113,11 +113,13 @@ static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *a
struct
inquiry_data
*
data
=
&
e
->
data
;
bdaddr_t
bdaddr
;
baswap
(
&
bdaddr
,
&
data
->
bdaddr
);
n
+=
sprintf
(
buf
+
n
,
"%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %u
\n
"
,
n
+=
sprintf
(
buf
+
n
,
"%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %
d %
u
\n
"
,
batostr
(
&
bdaddr
),
data
->
pscan_rep_mode
,
data
->
pscan_period_mode
,
data
->
pscan_mode
,
data
->
dev_class
[
2
],
data
->
dev_class
[
1
],
data
->
dev_class
[
0
],
__le16_to_cpu
(
data
->
clock_offset
),
data
->
rssi
,
e
->
timestamp
);
data
->
pscan_rep_mode
,
data
->
pscan_period_mode
,
data
->
pscan_mode
,
data
->
dev_class
[
2
],
data
->
dev_class
[
1
],
data
->
dev_class
[
0
],
__le16_to_cpu
(
data
->
clock_offset
),
data
->
rssi
,
data
->
ssp_mode
,
e
->
timestamp
);
}
hci_dev_unlock_bh
(
hdev
);
...
...
@@ -249,15 +251,28 @@ static ssize_t show_conn_address(struct device *dev, struct device_attribute *at
return
sprintf
(
buf
,
"%s
\n
"
,
batostr
(
&
bdaddr
));
}
static
ssize_t
show_conn_features
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
hci_conn
*
conn
=
dev_get_drvdata
(
dev
);
return
sprintf
(
buf
,
"0x%02x%02x%02x%02x%02x%02x%02x%02x
\n
"
,
conn
->
features
[
0
],
conn
->
features
[
1
],
conn
->
features
[
2
],
conn
->
features
[
3
],
conn
->
features
[
4
],
conn
->
features
[
5
],
conn
->
features
[
6
],
conn
->
features
[
7
]);
}
#define CONN_ATTR(_name,_mode,_show,_store) \
struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
static
CONN_ATTR
(
type
,
S_IRUGO
,
show_conn_type
,
NULL
);
static
CONN_ATTR
(
address
,
S_IRUGO
,
show_conn_address
,
NULL
);
static
CONN_ATTR
(
features
,
S_IRUGO
,
show_conn_features
,
NULL
);
static
struct
device_attribute
*
conn_attrs
[]
=
{
&
conn_attr_type
,
&
conn_attr_address
,
&
conn_attr_features
,
NULL
};
...
...
@@ -296,7 +311,6 @@ static void add_conn(struct work_struct *work)
void
hci_conn_add_sysfs
(
struct
hci_conn
*
conn
)
{
struct
hci_dev
*
hdev
=
conn
->
hdev
;
bdaddr_t
*
ba
=
&
conn
->
dst
;
BT_DBG
(
"conn %p"
,
conn
);
...
...
@@ -305,11 +319,8 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
conn
->
dev
.
release
=
bt_release
;
snprintf
(
conn
->
dev
.
bus_id
,
BUS_ID_SIZE
,
"%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X"
,
conn
->
type
==
ACL_LINK
?
"acl"
:
"sco"
,
ba
->
b
[
5
],
ba
->
b
[
4
],
ba
->
b
[
3
],
ba
->
b
[
2
],
ba
->
b
[
1
],
ba
->
b
[
0
]);
snprintf
(
conn
->
dev
.
bus_id
,
BUS_ID_SIZE
,
"%s:%d"
,
hdev
->
name
,
conn
->
handle
);
dev_set_drvdata
(
&
conn
->
dev
,
conn
);
...
...
net/bluetooth/hidp/core.c
View file @
407d819c
...
...
@@ -581,6 +581,12 @@ static int hidp_session(void *arg)
hid_free_device
(
session
->
hid
);
}
/* Wakeup user-space polling for socket errors */
session
->
intr_sock
->
sk
->
sk_err
=
EUNATCH
;
session
->
ctrl_sock
->
sk
->
sk_err
=
EUNATCH
;
hidp_schedule
(
session
);
fput
(
session
->
intr_sock
->
file
);
wait_event_timeout
(
*
(
ctrl_sk
->
sk_sleep
),
...
...
@@ -879,6 +885,10 @@ int hidp_del_connection(struct hidp_conndel_req *req)
skb_queue_purge
(
&
session
->
ctrl_transmit
);
skb_queue_purge
(
&
session
->
intr_transmit
);
/* Wakeup user-space polling for socket errors */
session
->
intr_sock
->
sk
->
sk_err
=
EUNATCH
;
session
->
ctrl_sock
->
sk
->
sk_err
=
EUNATCH
;
/* Kill session thread */
atomic_inc
(
&
session
->
terminate
);
hidp_schedule
(
session
);
...
...
net/bluetooth/l2cap.c
View file @
407d819c
This diff is collapsed.
Click to expand it.
net/bluetooth/rfcomm/core.c
View file @
407d819c
...
...
@@ -51,7 +51,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "1.
8
"
#define VERSION "1.
10
"
static
int
disable_cfc
=
0
;
static
int
channel_mtu
=
-
1
;
...
...
@@ -228,6 +228,21 @@ static int rfcomm_l2sock_create(struct socket **sock)
return
err
;
}
static
inline
int
rfcomm_check_link_mode
(
struct
rfcomm_dlc
*
d
)
{
struct
sock
*
sk
=
d
->
session
->
sock
->
sk
;
if
(
d
->
link_mode
&
(
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
))
{
if
(
!
hci_conn_encrypt
(
l2cap_pi
(
sk
)
->
conn
->
hcon
))
return
1
;
}
else
if
(
d
->
link_mode
&
RFCOMM_LM_AUTH
)
{
if
(
!
hci_conn_auth
(
l2cap_pi
(
sk
)
->
conn
->
hcon
))
return
1
;
}
return
0
;
}
/* ---- RFCOMM DLCs ---- */
static
void
rfcomm_dlc_timeout
(
unsigned
long
arg
)
{
...
...
@@ -369,15 +384,23 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
d
->
addr
=
__addr
(
s
->
initiator
,
dlci
);
d
->
priority
=
7
;
d
->
state
=
BT_CONFIG
;
d
->
state
=
BT_CONFIG
;
rfcomm_dlc_link
(
s
,
d
);
d
->
out
=
1
;
d
->
mtu
=
s
->
mtu
;
d
->
cfc
=
(
s
->
cfc
==
RFCOMM_CFC_UNKNOWN
)
?
0
:
s
->
cfc
;
if
(
s
->
state
==
BT_CONNECTED
)
rfcomm_send_pn
(
s
,
1
,
d
);
if
(
s
->
state
==
BT_CONNECTED
)
{
if
(
rfcomm_check_link_mode
(
d
))
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
else
rfcomm_send_pn
(
s
,
1
,
d
);
}
rfcomm_dlc_set_timer
(
d
,
RFCOMM_CONN_TIMEOUT
);
return
0
;
}
...
...
@@ -1144,21 +1167,6 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
return
0
;
}
static
inline
int
rfcomm_check_link_mode
(
struct
rfcomm_dlc
*
d
)
{
struct
sock
*
sk
=
d
->
session
->
sock
->
sk
;
if
(
d
->
link_mode
&
(
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
))
{
if
(
!
hci_conn_encrypt
(
l2cap_pi
(
sk
)
->
conn
->
hcon
))
return
1
;
}
else
if
(
d
->
link_mode
&
RFCOMM_LM_AUTH
)
{
if
(
!
hci_conn_auth
(
l2cap_pi
(
sk
)
->
conn
->
hcon
))
return
1
;
}
return
0
;
}
static
void
rfcomm_dlc_accept
(
struct
rfcomm_dlc
*
d
)
{
struct
sock
*
sk
=
d
->
session
->
sock
->
sk
;
...
...
@@ -1203,10 +1211,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
if
(
rfcomm_check_link_mode
(
d
))
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
return
0
;
}
rfcomm_dlc_accept
(
d
);
}
else
rfcomm_dlc_accept
(
d
);
}
return
0
;
}
...
...
@@ -1221,10 +1227,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
if
(
rfcomm_check_link_mode
(
d
))
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
return
0
;
}
rfcomm_dlc_accept
(
d
);
}
else
rfcomm_dlc_accept
(
d
);
}
else
{
rfcomm_send_dm
(
s
,
dlci
);
}
...
...
@@ -1457,8 +1461,12 @@ static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb
clear_bit
(
RFCOMM_TX_THROTTLED
,
&
d
->
flags
);
rfcomm_dlc_lock
(
d
);
d
->
remote_v24_sig
=
msc
->
v24_sig
;
if
(
d
->
modem_status
)
d
->
modem_status
(
d
,
msc
->
v24_sig
);
rfcomm_dlc_unlock
(
d
);
rfcomm_send_msc
(
s
,
0
,
dlci
,
msc
->
v24_sig
);
...
...
@@ -1634,7 +1642,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s)
d
=
list_entry
(
p
,
struct
rfcomm_dlc
,
list
);
if
(
d
->
state
==
BT_CONFIG
)
{
d
->
mtu
=
s
->
mtu
;
rfcomm_send_pn
(
s
,
1
,
d
);
if
(
rfcomm_check_link_mode
(
d
))
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
}
else
rfcomm_send_pn
(
s
,
1
,
d
);
}
}
}
...
...
@@ -1707,7 +1719,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
if
(
test_and_clear_bit
(
RFCOMM_AUTH_ACCEPT
,
&
d
->
flags
))
{
rfcomm_dlc_clear_timer
(
d
);
rfcomm_dlc_accept
(
d
);
if
(
d
->
out
)
{
rfcomm_send_pn
(
s
,
1
,
d
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_CONN_TIMEOUT
);
}
else
rfcomm_dlc_accept
(
d
);
if
(
d
->
link_mode
&
RFCOMM_LM_SECURE
)
{
struct
sock
*
sk
=
s
->
sock
->
sk
;
hci_conn_change_link_key
(
l2cap_pi
(
sk
)
->
conn
->
hcon
);
...
...
@@ -1715,7 +1731,10 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue
;
}
else
if
(
test_and_clear_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
))
{
rfcomm_dlc_clear_timer
(
d
);
rfcomm_send_dm
(
s
,
d
->
dlci
);
if
(
!
d
->
out
)
rfcomm_send_dm
(
s
,
d
->
dlci
);
else
d
->
state
=
BT_CLOSED
;
__rfcomm_dlc_close
(
d
,
ECONNREFUSED
);
continue
;
}
...
...
@@ -1724,7 +1743,7 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue
;
if
((
d
->
state
==
BT_CONNECTED
||
d
->
state
==
BT_DISCONN
)
&&
d
->
mscex
==
RFCOMM_MSCEX_OK
)
d
->
mscex
==
RFCOMM_MSCEX_OK
)
rfcomm_process_tx
(
d
);
}
}
...
...
@@ -1952,7 +1971,8 @@ static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status)
list_for_each_safe
(
p
,
n
,
&
s
->
dlcs
)
{
d
=
list_entry
(
p
,
struct
rfcomm_dlc
,
list
);
if
(
d
->
link_mode
&
(
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
))
if
((
d
->
link_mode
&
(
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
))
&&
!
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
&&
!
status
)
continue
;
if
(
!
test_and_clear_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
))
...
...
@@ -1986,6 +2006,14 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
list_for_each_safe
(
p
,
n
,
&
s
->
dlcs
)
{
d
=
list_entry
(
p
,
struct
rfcomm_dlc
,
list
);
if
((
d
->
link_mode
&
(
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
))
&&
(
d
->
state
==
BT_CONNECTED
||
d
->
state
==
BT_CONFIG
)
&&
!
status
&&
encrypt
==
0x00
)
{
__rfcomm_dlc_close
(
d
,
ECONNREFUSED
);
continue
;
}
if
(
!
test_and_clear_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
))
continue
;
...
...
net/bluetooth/rfcomm/sock.c
View file @
407d819c
...
...
@@ -307,13 +307,13 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int
sk
->
sk_destruct
=
rfcomm_sock_destruct
;
sk
->
sk_sndtimeo
=
RFCOMM_CONN_TIMEOUT
;
sk
->
sk_sndbuf
=
RFCOMM_MAX_CREDITS
*
RFCOMM_DEFAULT_MTU
*
10
;
sk
->
sk_rcvbuf
=
RFCOMM_MAX_CREDITS
*
RFCOMM_DEFAULT_MTU
*
10
;
sk
->
sk_sndbuf
=
RFCOMM_MAX_CREDITS
*
RFCOMM_DEFAULT_MTU
*
10
;
sk
->
sk_rcvbuf
=
RFCOMM_MAX_CREDITS
*
RFCOMM_DEFAULT_MTU
*
10
;
sock_reset_flag
(
sk
,
SOCK_ZAPPED
);
sk
->
sk_protocol
=
proto
;
sk
->
sk_state
=
BT_OPEN
;
sk
->
sk_state
=
BT_OPEN
;
bt_sock_link
(
&
rfcomm_sk_list
,
sk
);
...
...
@@ -411,6 +411,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
&
sa
->
rc_bdaddr
);
rfcomm_pi
(
sk
)
->
channel
=
sa
->
rc_channel
;
d
->
link_mode
=
rfcomm_pi
(
sk
)
->
link_mode
;
err
=
rfcomm_dlc_open
(
d
,
&
bt_sk
(
sk
)
->
src
,
&
sa
->
rc_bdaddr
,
sa
->
rc_channel
);
if
(
!
err
)
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
...
...
@@ -686,6 +688,8 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
copied
+=
chunk
;
size
-=
chunk
;
sock_recv_timestamp
(
msg
,
sk
,
skb
);
if
(
!
(
flags
&
MSG_PEEK
))
{
atomic_sub
(
chunk
,
&
sk
->
sk_rmem_alloc
);
...
...
@@ -791,15 +795,20 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
struct
sock
*
sk
=
sock
->
sk
;
int
err
;
lock_sock
(
sk
);
BT_DBG
(
"sk %p cmd %x arg %lx"
,
sk
,
cmd
,
arg
);
err
=
bt_sock_ioctl
(
sock
,
cmd
,
arg
);
if
(
err
==
-
ENOIOCTLCMD
)
{
#ifdef CONFIG_BT_RFCOMM_TTY
err
=
rfcomm_dev_ioctl
(
sk
,
cmd
,
(
void
__user
*
)
arg
);
lock_sock
(
sk
);
err
=
rfcomm_dev_ioctl
(
sk
,
cmd
,
(
void
__user
*
)
arg
);
release_sock
(
sk
);
#else
err
=
-
EOPNOTSUPP
;
err
=
-
EOPNOTSUPP
;
#endif
}
release_sock
(
sk
);
return
err
;
}
...
...
net/bluetooth/rfcomm/tty.c
View file @
407d819c
...
...
@@ -75,6 +75,8 @@ struct rfcomm_dev {
struct
device
*
tty_dev
;
atomic_t
wmem_alloc
;
struct
sk_buff_head
pending
;
};
static
LIST_HEAD
(
rfcomm_dev_list
);
...
...
@@ -262,13 +264,34 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
init_waitqueue_head
(
&
dev
->
wait
);
tasklet_init
(
&
dev
->
wakeup_task
,
rfcomm_tty_wakeup
,
(
unsigned
long
)
dev
);
skb_queue_head_init
(
&
dev
->
pending
);
rfcomm_dlc_lock
(
dlc
);
if
(
req
->
flags
&
(
1
<<
RFCOMM_REUSE_DLC
))
{
struct
sock
*
sk
=
dlc
->
owner
;
struct
sk_buff
*
skb
;
BUG_ON
(
!
sk
);
rfcomm_dlc_throttle
(
dlc
);
while
((
skb
=
skb_dequeue
(
&
sk
->
sk_receive_queue
)))
{
skb_orphan
(
skb
);
skb_queue_tail
(
&
dev
->
pending
,
skb
);
atomic_sub
(
skb
->
len
,
&
sk
->
sk_rmem_alloc
);
}
}
dlc
->
data_ready
=
rfcomm_dev_data_ready
;
dlc
->
state_change
=
rfcomm_dev_state_change
;
dlc
->
modem_status
=
rfcomm_dev_modem_status
;
dlc
->
owner
=
dev
;
dev
->
dlc
=
dlc
;
rfcomm_dev_modem_status
(
dlc
,
dlc
->
remote_v24_sig
);
rfcomm_dlc_unlock
(
dlc
);
/* It's safe to call __module_get() here because socket already
...
...
@@ -537,11 +560,16 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
struct
rfcomm_dev
*
dev
=
dlc
->
owner
;
struct
tty_struct
*
tty
;
if
(
!
dev
||
!
(
tty
=
dev
->
tty
)
)
{
if
(
!
dev
)
{
kfree_skb
(
skb
);
return
;
}
if
(
!
(
tty
=
dev
->
tty
)
||
!
skb_queue_empty
(
&
dev
->
pending
))
{
skb_queue_tail
(
&
dev
->
pending
,
skb
);
return
;
}
BT_DBG
(
"dlc %p tty %p len %d"
,
dlc
,
tty
,
skb
->
len
);
tty_insert_flip_string
(
tty
,
skb
->
data
,
skb
->
len
);
...
...
@@ -625,6 +653,30 @@ static void rfcomm_tty_wakeup(unsigned long arg)
#endif
}
static
void
rfcomm_tty_copy_pending
(
struct
rfcomm_dev
*
dev
)
{
struct
tty_struct
*
tty
=
dev
->
tty
;
struct
sk_buff
*
skb
;
int
inserted
=
0
;
if
(
!
tty
)
return
;
BT_DBG
(
"dev %p tty %p"
,
dev
,
tty
);
rfcomm_dlc_lock
(
dev
->
dlc
);
while
((
skb
=
skb_dequeue
(
&
dev
->
pending
)))
{
inserted
+=
tty_insert_flip_string
(
tty
,
skb
->
data
,
skb
->
len
);
kfree_skb
(
skb
);
}
rfcomm_dlc_unlock
(
dev
->
dlc
);
if
(
inserted
>
0
)
tty_flip_buffer_push
(
tty
);
}
static
int
rfcomm_tty_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
...
...
@@ -689,6 +741,10 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
if
(
err
==
0
)
device_move
(
dev
->
tty_dev
,
rfcomm_get_device
(
dev
));
rfcomm_tty_copy_pending
(
dev
);
rfcomm_dlc_unthrottle
(
dev
->
dlc
);
return
err
;
}
...
...
@@ -1121,6 +1177,7 @@ int rfcomm_init_ttys(void)
rfcomm_tty_driver
->
flags
=
TTY_DRIVER_REAL_RAW
|
TTY_DRIVER_DYNAMIC_DEV
;
rfcomm_tty_driver
->
init_termios
=
tty_std_termios
;
rfcomm_tty_driver
->
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
|
CLOCAL
;
rfcomm_tty_driver
->
init_termios
.
c_lflag
&=
~
ICANON
;
tty_set_operations
(
rfcomm_tty_driver
,
&
rfcomm_ops
);
if
(
tty_register_driver
(
rfcomm_tty_driver
))
{
...
...
net/bluetooth/sco.c
View file @
407d819c
...
...
@@ -53,7 +53,9 @@
#define BT_DBG(D...)
#endif
#define VERSION "0.5"
#define VERSION "0.6"
static
int
disable_esco
=
0
;
static
const
struct
proto_ops
sco_sock_ops
;
...
...
@@ -193,7 +195,10 @@ static int sco_connect(struct sock *sk)
err
=
-
ENOMEM
;
type
=
lmp_esco_capable
(
hdev
)
?
ESCO_LINK
:
SCO_LINK
;
if
(
lmp_esco_capable
(
hdev
)
&&
!
disable_esco
)
type
=
ESCO_LINK
;
else
type
=
SCO_LINK
;
hcon
=
hci_connect
(
hdev
,
type
,
dst
);
if
(
!
hcon
)
...
...
@@ -921,7 +926,7 @@ static const struct proto_ops sco_sock_ops = {
.
sendmsg
=
sco_sock_sendmsg
,
.
recvmsg
=
bt_sock_recvmsg
,
.
poll
=
bt_sock_poll
,
.
ioctl
=
sock_no
_ioctl
,
.
ioctl
=
bt_sock
_ioctl
,
.
mmap
=
sock_no_mmap
,
.
socketpair
=
sock_no_socketpair
,
.
shutdown
=
sock_no_shutdown
,
...
...
@@ -994,6 +999,9 @@ static void __exit sco_exit(void)
module_init
(
sco_init
);
module_exit
(
sco_exit
);
module_param
(
disable_esco
,
bool
,
0644
);
MODULE_PARM_DESC
(
disable_esco
,
"Disable eSCO connection creation"
);
MODULE_AUTHOR
(
"Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth SCO ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
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