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
63748aa8
Commit
63748aa8
authored
Feb 26, 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
43be6366
b1fb0683
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
968 additions
and
362 deletions
+968
-362
drivers/bluetooth/bfusb.c
drivers/bluetooth/bfusb.c
+1
-2
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/bt3c_cs.c
+2
-2
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+23
-17
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_h4.c
+1
-2
drivers/bluetooth/hci_ll.c
drivers/bluetooth/hci_ll.c
+1
-2
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+12
-0
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+8
-0
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+57
-27
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+10
-3
include/net/bluetooth/rfcomm.h
include/net/bluetooth/rfcomm.h
+12
-8
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+7
-10
net/bluetooth/cmtp/core.c
net/bluetooth/cmtp/core.c
+1
-2
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+41
-23
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+1
-2
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+21
-5
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+440
-162
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+100
-79
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+179
-10
net/bluetooth/sco.c
net/bluetooth/sco.c
+51
-6
No files found.
drivers/bluetooth/bfusb.c
View file @
63748aa8
...
...
@@ -257,8 +257,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
if
(
hdr
&
0x10
)
{
BT_ERR
(
"%s error in block"
,
data
->
hdev
->
name
);
if
(
data
->
reassembly
)
kfree_skb
(
data
->
reassembly
);
kfree_skb
(
data
->
reassembly
);
data
->
reassembly
=
NULL
;
return
-
EIO
;
}
...
...
drivers/bluetooth/bt3c_cs.c
View file @
63748aa8
...
...
@@ -359,9 +359,9 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
BT_ERR
(
"Very strange (stat=0x%04x)"
,
stat
);
}
else
if
((
stat
&
0xff
)
!=
0xff
)
{
if
(
stat
&
0x0020
)
{
int
stat
=
bt3c_read
(
iobase
,
0x7002
)
&
0x10
;
int
stat
us
=
bt3c_read
(
iobase
,
0x7002
)
&
0x10
;
BT_INFO
(
"%s: Antenna %s"
,
info
->
hdev
->
name
,
stat
?
"out"
:
"in"
);
stat
us
?
"out"
:
"in"
);
}
if
(
stat
&
0x0001
)
bt3c_receive
(
info
);
...
...
drivers/bluetooth/btusb.c
View file @
63748aa8
...
...
@@ -35,7 +35,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#define VERSION "0.
4
"
#define VERSION "0.
5
"
static
int
ignore_dga
;
static
int
ignore_csr
;
...
...
@@ -171,6 +171,7 @@ struct btusb_data {
__u8
cmdreq_type
;
unsigned
int
sco_num
;
int
isoc_altsetting
;
int
suspend_count
;
};
...
...
@@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hdev)
return
0
;
err
=
btusb_submit_intr_urb
(
hdev
,
GFP_KERNEL
);
if
(
err
<
0
)
goto
failed
;
err
=
btusb_submit_bulk_urb
(
hdev
,
GFP_KERNEL
);
if
(
err
<
0
)
{
clear_bit
(
BTUSB_INTR_RUNNING
,
&
data
->
flags
);
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
)
;
usb_kill_anchored_urbs
(
&
data
->
intr_anchor
);
goto
failed
;
}
set_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
btusb_submit_bulk_urb
(
hdev
,
GFP_KERNEL
);
return
0
;
failed:
clear_bit
(
BTUSB_INTR_RUNNING
,
&
data
->
flags
);
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
return
err
;
}
...
...
@@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG
(
"%s evt %d"
,
hdev
->
name
,
evt
);
if
(
hdev
->
conn_hash
.
acl_num
>
0
)
{
if
(
!
test_and_set_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
))
{
if
(
btusb_submit_bulk_urb
(
hdev
,
GFP_ATOMIC
)
<
0
)
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
else
btusb_submit_bulk_urb
(
hdev
,
GFP_ATOMIC
);
}
}
else
{
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
usb_unlink_anchored_urbs
(
&
data
->
bulk_anchor
);
if
(
hdev
->
conn_hash
.
sco_num
!=
data
->
sco_num
)
{
data
->
sco_num
=
hdev
->
conn_hash
.
sco_num
;
schedule_work
(
&
data
->
work
);
}
schedule_work
(
&
data
->
work
);
}
static
int
inline
__set_isoc_interface
(
struct
hci_dev
*
hdev
,
int
altsetting
)
...
...
@@ -982,9 +986,11 @@ static int btusb_resume(struct usb_interface *intf)
}
if
(
test_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
))
{
if
(
btusb_submit_bulk_urb
(
hdev
,
GFP_NOIO
)
<
0
)
err
=
btusb_submit_bulk_urb
(
hdev
,
GFP_NOIO
);
if
(
err
<
0
)
{
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
else
return
err
;
}
else
btusb_submit_bulk_urb
(
hdev
,
GFP_NOIO
);
}
...
...
drivers/bluetooth/hci_h4.c
View file @
63748aa8
...
...
@@ -102,8 +102,7 @@ static int h4_close(struct hci_uart *hu)
skb_queue_purge
(
&
h4
->
txq
);
if
(
h4
->
rx_skb
)
kfree_skb
(
h4
->
rx_skb
);
kfree_skb
(
h4
->
rx_skb
);
hu
->
priv
=
NULL
;
kfree
(
h4
);
...
...
drivers/bluetooth/hci_ll.c
View file @
63748aa8
...
...
@@ -163,8 +163,7 @@ static int ll_close(struct hci_uart *hu)
skb_queue_purge
(
&
ll
->
tx_wait_q
);
skb_queue_purge
(
&
ll
->
txq
);
if
(
ll
->
rx_skb
)
kfree_skb
(
ll
->
rx_skb
);
kfree_skb
(
ll
->
rx_skb
);
hu
->
priv
=
NULL
;
...
...
include/net/bluetooth/bluetooth.h
View file @
63748aa8
...
...
@@ -53,6 +53,17 @@
#define SOL_SCO 17
#define SOL_RFCOMM 18
#define BT_SECURITY 4
struct
bt_security
{
__u8
level
;
};
#define BT_SECURITY_SDP 0
#define BT_SECURITY_LOW 1
#define BT_SECURITY_MEDIUM 2
#define BT_SECURITY_HIGH 3
#define BT_DEFER_SETUP 7
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
...
...
@@ -108,6 +119,7 @@ struct bt_sock {
bdaddr_t
dst
;
struct
list_head
accept_q
;
struct
sock
*
parent
;
u32
defer_setup
;
};
struct
bt_sock_list
{
...
...
include/net/bluetooth/hci.h
View file @
63748aa8
...
...
@@ -133,8 +133,13 @@ enum {
#define ESCO_EV3 0x0008
#define ESCO_EV4 0x0010
#define ESCO_EV5 0x0020
#define ESCO_2EV3 0x0040
#define ESCO_3EV3 0x0080
#define ESCO_2EV5 0x0100
#define ESCO_3EV5 0x0200
#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
/* ACL flags */
#define ACL_CONT 0x01
...
...
@@ -176,6 +181,9 @@ enum {
#define LMP_EV5 0x02
#define LMP_SNIFF_SUBR 0x02
#define LMP_EDR_ESCO_2M 0x20
#define LMP_EDR_ESCO_3M 0x40
#define LMP_EDR_3S_ESCO 0x80
#define LMP_SIMPLE_PAIR 0x08
...
...
include/net/bluetooth/hci_core.h
View file @
63748aa8
...
...
@@ -169,6 +169,7 @@ struct hci_conn {
__u16
link_policy
;
__u32
link_mode
;
__u8
auth_type
;
__u8
sec_level
;
__u8
power_save
;
unsigned
long
pend
;
...
...
@@ -325,12 +326,11 @@ int hci_conn_del(struct hci_conn *conn);
void
hci_conn_hash_flush
(
struct
hci_dev
*
hdev
);
void
hci_conn_check_pending
(
struct
hci_dev
*
hdev
);
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
auth_type
);
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
sec_level
,
__u8
auth_type
);
int
hci_conn_check_link_mode
(
struct
hci_conn
*
conn
);
int
hci_conn_auth
(
struct
hci_conn
*
conn
);
int
hci_conn_encrypt
(
struct
hci_conn
*
conn
);
int
hci_conn_security
(
struct
hci_conn
*
conn
,
__u8
sec_level
,
__u8
auth_type
);
int
hci_conn_change_link_key
(
struct
hci_conn
*
conn
);
int
hci_conn_switch_role
(
struct
hci_conn
*
conn
,
uint8_t
role
);
int
hci_conn_switch_role
(
struct
hci_conn
*
conn
,
__u8
role
);
void
hci_conn_enter_active_mode
(
struct
hci_conn
*
conn
);
void
hci_conn_enter_sniff_mode
(
struct
hci_conn
*
conn
);
...
...
@@ -470,26 +470,26 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
/* ----- HCI protocols ----- */
struct
hci_proto
{
char
*
name
;
char
*
name
;
unsigned
int
id
;
unsigned
long
flags
;
void
*
priv
;
int
(
*
connect_ind
)
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
__u8
type
);
int
(
*
connect_ind
)
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
__u8
type
);
int
(
*
connect_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
);
int
(
*
disconn_ind
)
(
struct
hci_conn
*
conn
,
__u8
reason
);
int
(
*
disconn_ind
)
(
struct
hci_conn
*
conn
);
int
(
*
disconn_cfm
)
(
struct
hci_conn
*
conn
,
__u8
reason
);
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
,
__u8
encrypt
);
int
(
*
security_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
)
{
register
struct
hci_proto
*
hp
;
int
mask
=
0
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
connect_ind
)
mask
|=
hp
->
connect_ind
(
hdev
,
bdaddr
,
type
);
...
...
@@ -514,30 +514,52 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
hp
->
connect_cfm
(
conn
,
status
);
}
static
inline
void
hci_proto_disconn_ind
(
struct
hci_conn
*
conn
,
__u8
reaso
n
)
static
inline
int
hci_proto_disconn_ind
(
struct
hci_conn
*
con
n
)
{
register
struct
hci_proto
*
hp
;
int
reason
=
0x13
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
disconn_ind
)
hp
->
disconn_ind
(
conn
,
reaso
n
);
reason
=
hp
->
disconn_ind
(
con
n
);
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
disconn_ind
)
hp
->
disconn_ind
(
conn
,
reason
);
reason
=
hp
->
disconn_ind
(
conn
);
return
reason
;
}
static
inline
void
hci_proto_disconn_cfm
(
struct
hci_conn
*
conn
,
__u8
reason
)
{
register
struct
hci_proto
*
hp
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
disconn_cfm
)
hp
->
disconn_cfm
(
conn
,
reason
);
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
disconn_cfm
)
hp
->
disconn_cfm
(
conn
,
reason
);
}
static
inline
void
hci_proto_auth_cfm
(
struct
hci_conn
*
conn
,
__u8
status
)
{
register
struct
hci_proto
*
hp
;
__u8
encrypt
;
if
(
test_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
return
;
encrypt
=
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
?
0x01
:
0x00
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
auth
_cfm
)
hp
->
auth_cfm
(
conn
,
status
);
if
(
hp
&&
hp
->
security
_cfm
)
hp
->
security_cfm
(
conn
,
status
,
encrypt
);
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
auth
_cfm
)
hp
->
auth_cfm
(
conn
,
status
);
if
(
hp
&&
hp
->
security
_cfm
)
hp
->
security_cfm
(
conn
,
status
,
encrypt
);
}
static
inline
void
hci_proto_encrypt_cfm
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
encrypt
)
...
...
@@ -545,12 +567,12 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u
register
struct
hci_proto
*
hp
;
hp
=
hci_proto
[
HCI_PROTO_L2CAP
];
if
(
hp
&&
hp
->
encrypt
_cfm
)
hp
->
encrypt
_cfm
(
conn
,
status
,
encrypt
);
if
(
hp
&&
hp
->
security
_cfm
)
hp
->
security
_cfm
(
conn
,
status
,
encrypt
);
hp
=
hci_proto
[
HCI_PROTO_SCO
];
if
(
hp
&&
hp
->
encrypt
_cfm
)
hp
->
encrypt
_cfm
(
conn
,
status
,
encrypt
);
if
(
hp
&&
hp
->
security
_cfm
)
hp
->
security
_cfm
(
conn
,
status
,
encrypt
);
}
int
hci_register_proto
(
struct
hci_proto
*
hproto
);
...
...
@@ -562,8 +584,7 @@ struct hci_cb {
char
*
name
;
void
(
*
auth_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
);
void
(
*
encrypt_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
encrypt
);
void
(
*
security_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
encrypt
);
void
(
*
key_change_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
);
void
(
*
role_switch_cfm
)
(
struct
hci_conn
*
conn
,
__u8
status
,
__u8
role
);
};
...
...
@@ -571,14 +592,20 @@ struct hci_cb {
static
inline
void
hci_auth_cfm
(
struct
hci_conn
*
conn
,
__u8
status
)
{
struct
list_head
*
p
;
__u8
encrypt
;
hci_proto_auth_cfm
(
conn
,
status
);
if
(
test_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
return
;
encrypt
=
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
?
0x01
:
0x00
;
read_lock_bh
(
&
hci_cb_list_lock
);
list_for_each
(
p
,
&
hci_cb_list
)
{
struct
hci_cb
*
cb
=
list_entry
(
p
,
struct
hci_cb
,
list
);
if
(
cb
->
auth
_cfm
)
cb
->
auth_cfm
(
conn
,
status
);
if
(
cb
->
security
_cfm
)
cb
->
security_cfm
(
conn
,
status
,
encrypt
);
}
read_unlock_bh
(
&
hci_cb_list_lock
);
}
...
...
@@ -587,13 +614,16 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
{
struct
list_head
*
p
;
if
(
conn
->
sec_level
==
BT_SECURITY_SDP
)
conn
->
sec_level
=
BT_SECURITY_LOW
;
hci_proto_encrypt_cfm
(
conn
,
status
,
encrypt
);
read_lock_bh
(
&
hci_cb_list_lock
);
list_for_each
(
p
,
&
hci_cb_list
)
{
struct
hci_cb
*
cb
=
list_entry
(
p
,
struct
hci_cb
,
list
);
if
(
cb
->
encrypt
_cfm
)
cb
->
encrypt
_cfm
(
conn
,
status
,
encrypt
);
if
(
cb
->
security
_cfm
)
cb
->
security
_cfm
(
conn
,
status
,
encrypt
);
}
read_unlock_bh
(
&
hci_cb_list_lock
);
}
...
...
include/net/bluetooth/l2cap.h
View file @
63748aa8
...
...
@@ -37,6 +37,7 @@ struct sockaddr_l2 {
sa_family_t
l2_family
;
__le16
l2_psm
;
bdaddr_t
l2_bdaddr
;
__le16
l2_cid
;
};
/* L2CAP socket options */
...
...
@@ -185,6 +186,7 @@ struct l2cap_info_rsp {
/* info type */
#define L2CAP_IT_CL_MTU 0x0001
#define L2CAP_IT_FEAT_MASK 0x0002
#define L2CAP_IT_FIXED_CHAN 0x0003
/* info result */
#define L2CAP_IR_SUCCESS 0x0000
...
...
@@ -219,11 +221,14 @@ struct l2cap_conn {
__u8
rx_ident
;
__u8
tx_ident
;
__u8
disc_reason
;
struct
l2cap_chan_list
chan_list
;
};
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x02
#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
/* ----- L2CAP channel and socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
...
...
@@ -237,8 +242,9 @@ struct l2cap_pinfo {
__u16
imtu
;
__u16
omtu
;
__u16
flush_to
;
__u32
link_mode
;
__u8
sec_level
;
__u8
role_switch
;
__u8
force_reliable
;
__u8
conf_req
[
64
];
__u8
conf_len
;
...
...
@@ -257,6 +263,7 @@ struct l2cap_pinfo {
#define L2CAP_CONF_REQ_SENT 0x01
#define L2CAP_CONF_INPUT_DONE 0x02
#define L2CAP_CONF_OUTPUT_DONE 0x04
#define L2CAP_CONF_CONNECT_PEND 0x80
#define L2CAP_CONF_MAX_RETRIES 2
...
...
include/net/bluetooth/rfcomm.h
View file @
63748aa8
...
...
@@ -183,8 +183,9 @@ struct rfcomm_dlc {
u8
remote_v24_sig
;
u8
mscex
;
u8
out
;
u32
link_mode
;
u8
sec_level
;
u8
role_switch
;
u32
defer_setup
;
uint
mtu
;
uint
cfc
;
...
...
@@ -202,10 +203,12 @@ struct rfcomm_dlc {
#define RFCOMM_RX_THROTTLED 0
#define RFCOMM_TX_THROTTLED 1
#define RFCOMM_TIMED_OUT 2
#define RFCOMM_MSC_PENDING 3
#define RFCOMM_AUTH_PENDING 4
#define RFCOMM_AUTH_ACCEPT 5
#define RFCOMM_AUTH_REJECT 6
#define RFCOMM_MSC_PENDING 3
#define RFCOMM_SEC_PENDING 4
#define RFCOMM_AUTH_PENDING 5
#define RFCOMM_AUTH_ACCEPT 6
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
/* Scheduling flags and events */
#define RFCOMM_SCHED_STATE 0
...
...
@@ -239,6 +242,7 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
int
rfcomm_dlc_send
(
struct
rfcomm_dlc
*
d
,
struct
sk_buff
*
skb
);
int
rfcomm_dlc_set_modem_status
(
struct
rfcomm_dlc
*
d
,
u8
v24_sig
);
int
rfcomm_dlc_get_modem_status
(
struct
rfcomm_dlc
*
d
,
u8
*
v24_sig
);
void
rfcomm_dlc_accept
(
struct
rfcomm_dlc
*
d
);
#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
...
...
@@ -304,7 +308,8 @@ struct rfcomm_pinfo {
struct
bt_sock
bt
;
struct
rfcomm_dlc
*
dlc
;
u8
channel
;
u32
link_mode
;
u8
sec_level
;
u8
role_switch
;
};
int
rfcomm_init_sockets
(
void
);
...
...
@@ -333,7 +338,6 @@ struct rfcomm_dev_req {
bdaddr_t
src
;
bdaddr_t
dst
;
u8
channel
;
};
struct
rfcomm_dev_info
{
...
...
net/bluetooth/af_bluetooth.c
View file @
63748aa8
...
...
@@ -41,14 +41,13 @@
#include <net/bluetooth/bluetooth.h>
#define VERSION "2.1
4
"
#define VERSION "2.1
5
"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
static
struct
net_proto_family
*
bt_proto
[
BT_MAX_PROTO
];
static
DEFINE_RWLOCK
(
bt_proto_lock
);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static
struct
lock_class_key
bt_lock_key
[
BT_MAX_PROTO
];
static
const
char
*
bt_key_strings
[
BT_MAX_PROTO
]
=
{
"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP"
,
...
...
@@ -86,11 +85,6 @@ static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
bt_slock_key_strings
[
proto
],
&
bt_slock_key
[
proto
],
bt_key_strings
[
proto
],
&
bt_lock_key
[
proto
]);
}
#else
static
inline
void
bt_sock_reclassify_lock
(
struct
socket
*
sock
,
int
proto
)
{
}
#endif
int
bt_sock_register
(
int
proto
,
struct
net_proto_family
*
ops
)
{
...
...
@@ -217,7 +211,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
continue
;
}
if
(
sk
->
sk_state
==
BT_CONNECTED
||
!
newsock
)
{
if
(
sk
->
sk_state
==
BT_CONNECTED
||
!
newsock
||
bt_sk
(
parent
)
->
defer_setup
)
{
bt_accept_unlink
(
sk
);
if
(
newsock
)
sock_graft
(
sk
,
newsock
);
...
...
@@ -232,7 +227,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
EXPORT_SYMBOL
(
bt_accept_dequeue
);
int
bt_sock_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
struct
msghdr
*
msg
,
size_t
len
,
int
flags
)
struct
msghdr
*
msg
,
size_t
len
,
int
flags
)
{
int
noblock
=
flags
&
MSG_DONTWAIT
;
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -277,7 +272,9 @@ static inline unsigned int bt_accept_poll(struct sock *parent)
list_for_each_safe
(
p
,
n
,
&
bt_sk
(
parent
)
->
accept_q
)
{
sk
=
(
struct
sock
*
)
list_entry
(
p
,
struct
bt_sock
,
accept_q
);
if
(
sk
->
sk_state
==
BT_CONNECTED
)
if
(
sk
->
sk_state
==
BT_CONNECTED
||
(
bt_sk
(
parent
)
->
defer_setup
&&
sk
->
sk_state
==
BT_CONNECT2
))
return
POLLIN
|
POLLRDNORM
;
}
...
...
net/bluetooth/cmtp/core.c
View file @
63748aa8
...
...
@@ -126,8 +126,7 @@ static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const
session
->
reassembly
[
id
]
=
nskb
;
if
(
skb
)
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
static
inline
int
cmtp_recv_frame
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
)
...
...
net/bluetooth/hci_conn.c
View file @
63748aa8
...
...
@@ -123,6 +123,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
conn
->
state
=
BT_CONNECT
;
conn
->
out
=
1
;
conn
->
attempt
++
;
cp
.
handle
=
cpu_to_le16
(
handle
);
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt_type
);
...
...
@@ -139,6 +141,8 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
conn
->
state
=
BT_CONNECT
;
conn
->
out
=
1
;
conn
->
attempt
++
;
cp
.
handle
=
cpu_to_le16
(
handle
);
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt_type
);
...
...
@@ -155,6 +159,7 @@ static void hci_conn_timeout(unsigned long arg)
{
struct
hci_conn
*
conn
=
(
void
*
)
arg
;
struct
hci_dev
*
hdev
=
conn
->
hdev
;
__u8
reason
;
BT_DBG
(
"conn %p state %d"
,
conn
,
conn
->
state
);
...
...
@@ -173,7 +178,8 @@ static void hci_conn_timeout(unsigned long arg)
break
;
case
BT_CONFIG
:
case
BT_CONNECTED
:
hci_acl_disconn
(
conn
,
0x13
);
reason
=
hci_proto_disconn_ind
(
conn
);
hci_acl_disconn
(
conn
,
reason
);
break
;
default:
conn
->
state
=
BT_CLOSED
;
...
...
@@ -216,12 +222,13 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
break
;
case
SCO_LINK
:
if
(
lmp_esco_capable
(
hdev
))
conn
->
pkt_type
=
hdev
->
esco_type
&
SCO_ESCO_MASK
;
conn
->
pkt_type
=
(
hdev
->
esco_type
&
SCO_ESCO_MASK
)
|
(
hdev
->
esco_type
&
EDR_ESCO_MASK
);
else
conn
->
pkt_type
=
hdev
->
pkt_type
&
SCO_PTYPE_MASK
;
break
;
case
ESCO_LINK
:
conn
->
pkt_type
=
hdev
->
esco_type
;
conn
->
pkt_type
=
hdev
->
esco_type
&
~
EDR_ESCO_MASK
;
break
;
}
...
...
@@ -280,6 +287,8 @@ int hci_conn_del(struct hci_conn *conn)
skb_queue_purge
(
&
conn
->
data_q
);
hci_conn_del_sysfs
(
conn
);
return
0
;
}
...
...
@@ -325,7 +334,7 @@ EXPORT_SYMBOL(hci_get_route);
/* Create SCO or ACL connection.
* Device _must_ be locked */
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
auth_type
)
struct
hci_conn
*
hci_connect
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
,
__u8
sec_level
,
__u8
auth_type
)
{
struct
hci_conn
*
acl
;
struct
hci_conn
*
sco
;
...
...
@@ -340,6 +349,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
hci_conn_hold
(
acl
);
if
(
acl
->
state
==
BT_OPEN
||
acl
->
state
==
BT_CLOSED
)
{
acl
->
sec_level
=
sec_level
;
acl
->
auth_type
=
auth_type
;
hci_acl_connect
(
acl
);
}
...
...
@@ -385,51 +395,59 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
EXPORT_SYMBOL
(
hci_conn_check_link_mode
);
/* Authenticate remote device */
int
hci_conn_auth
(
struct
hci_conn
*
conn
)
static
int
hci_conn_auth
(
struct
hci_conn
*
conn
,
__u8
sec_level
,
__u8
auth_type
)
{
BT_DBG
(
"conn %p"
,
conn
);
if
(
conn
->
ssp_mode
>
0
&&
conn
->
hdev
->
ssp_mode
>
0
)
{
if
(
!
(
conn
->
auth_type
&
0x01
))
{
conn
->
auth_type
|=
0x01
;
conn
->
link_mode
&=
~
HCI_LM_AUTH
;
}
}
if
(
conn
->
link_mode
&
HCI_LM_AUTH
)
if
(
sec_level
>
conn
->
sec_level
)
conn
->
sec_level
=
sec_level
;
else
if
(
conn
->
link_mode
&
HCI_LM_AUTH
)
return
1
;
conn
->
auth_type
=
auth_type
;
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
);
}
return
0
;
}
EXPORT_SYMBOL
(
hci_conn_auth
);
/* Enable
encryption
*/
int
hci_conn_
encrypt
(
struct
hci_conn
*
conn
)
/* Enable
security
*/
int
hci_conn_
security
(
struct
hci_conn
*
conn
,
__u8
sec_level
,
__u8
auth_type
)
{
BT_DBG
(
"conn %p"
,
conn
);
if
(
sec_level
==
BT_SECURITY_SDP
)
return
1
;
if
(
sec_level
==
BT_SECURITY_LOW
)
{
if
(
conn
->
ssp_mode
>
0
&&
conn
->
hdev
->
ssp_mode
>
0
)
return
hci_conn_auth
(
conn
,
sec_level
,
auth_type
);
else
return
1
;
}
if
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
return
hci_conn_auth
(
conn
);
return
hci_conn_auth
(
conn
,
sec_level
,
auth_type
);
if
(
test_and_set_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
return
0
;
if
(
hci_conn_auth
(
conn
))
{
if
(
hci_conn_auth
(
conn
,
sec_level
,
auth_type
))
{
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
);
}
return
0
;
}
EXPORT_SYMBOL
(
hci_conn_
encrypt
);
EXPORT_SYMBOL
(
hci_conn_
security
);
/* Change link key */
int
hci_conn_change_link_key
(
struct
hci_conn
*
conn
)
...
...
@@ -442,12 +460,13 @@ int hci_conn_change_link_key(struct hci_conn *conn)
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_CHANGE_CONN_LINK_KEY
,
sizeof
(
cp
),
&
cp
);
}
return
0
;
}
EXPORT_SYMBOL
(
hci_conn_change_link_key
);
/* Switch role */
int
hci_conn_switch_role
(
struct
hci_conn
*
conn
,
uint8_t
role
)
int
hci_conn_switch_role
(
struct
hci_conn
*
conn
,
__u8
role
)
{
BT_DBG
(
"conn %p"
,
conn
);
...
...
@@ -460,6 +479,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
cp
.
role
=
role
;
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_SWITCH_ROLE
,
sizeof
(
cp
),
&
cp
);
}
return
0
;
}
EXPORT_SYMBOL
(
hci_conn_switch_role
);
...
...
@@ -542,9 +562,7 @@ 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_proto_disconn_cfm
(
c
,
0x16
);
hci_conn_del
(
c
);
}
}
...
...
net/bluetooth/hci_core.c
View file @
63748aa8
...
...
@@ -1565,8 +1565,7 @@ static void hci_cmd_task(unsigned long arg)
/* Send queued commands */
if
(
atomic_read
(
&
hdev
->
cmd_cnt
)
&&
(
skb
=
skb_dequeue
(
&
hdev
->
cmd_q
)))
{
if
(
hdev
->
sent_cmd
)
kfree_skb
(
hdev
->
sent_cmd
);
kfree_skb
(
hdev
->
sent_cmd
);
if
((
hdev
->
sent_cmd
=
skb_clone
(
skb
,
GFP_ATOMIC
)))
{
atomic_dec
(
&
hdev
->
cmd_cnt
);
...
...
net/bluetooth/hci_event.c
View file @
63748aa8
...
...
@@ -484,6 +484,15 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb
if
(
hdev
->
features
[
4
]
&
LMP_EV5
)
hdev
->
esco_type
|=
(
ESCO_EV5
);
if
(
hdev
->
features
[
5
]
&
LMP_EDR_ESCO_2M
)
hdev
->
esco_type
|=
(
ESCO_2EV3
);
if
(
hdev
->
features
[
5
]
&
LMP_EDR_ESCO_3M
)
hdev
->
esco_type
|=
(
ESCO_3EV3
);
if
(
hdev
->
features
[
5
]
&
LMP_EDR_3S_ESCO
)
hdev
->
esco_type
|=
(
ESCO_2EV5
|
ESCO_3EV5
);
BT_DBG
(
"%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x"
,
hdev
->
name
,
hdev
->
features
[
0
],
hdev
->
features
[
1
],
hdev
->
features
[
2
],
hdev
->
features
[
3
],
...
...
@@ -914,7 +923,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if
(
ev
->
status
)
{
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
hci_conn_del
(
conn
);
}
}
else
if
(
ev
->
link_type
!=
ACL_LINK
)
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
unlock:
hci_dev_unlock
(
hdev
);
...
...
@@ -1009,9 +1019,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
if
(
conn
)
{
conn
->
state
=
BT_CLOSED
;
hci_conn_del_sysfs
(
conn
);
hci_proto_disconn_ind
(
conn
,
ev
->
reason
);
hci_proto_disconn_cfm
(
conn
,
ev
->
reason
);
hci_conn_del
(
conn
);
}
...
...
@@ -1600,7 +1608,8 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
if
(
conn
->
state
==
BT_CONFIG
)
{
if
(
!
ev
->
status
&&
hdev
->
ssp_mode
>
0
&&
conn
->
ssp_mode
>
0
&&
conn
->
out
)
{
conn
->
ssp_mode
>
0
&&
conn
->
out
&&
conn
->
sec_level
!=
BT_SECURITY_SDP
)
{
struct
hci_cp_auth_requested
cp
;
cp
.
handle
=
ev
->
handle
;
hci_send_cmd
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
...
...
@@ -1637,6 +1646,13 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
conn
->
type
=
SCO_LINK
;
}
if
(
conn
->
out
&&
ev
->
status
==
0x1c
&&
conn
->
attempt
<
2
)
{
conn
->
pkt_type
=
(
hdev
->
esco_type
&
SCO_ESCO_MASK
)
|
(
hdev
->
esco_type
&
EDR_ESCO_MASK
);
hci_setup_sync
(
conn
,
conn
->
link
->
handle
);
goto
unlock
;
}
if
(
!
ev
->
status
)
{
conn
->
handle
=
__le16_to_cpu
(
ev
->
handle
);
conn
->
state
=
BT_CONNECTED
;
...
...
net/bluetooth/l2cap.c
View file @
63748aa8
This diff is collapsed.
Click to expand it.
net/bluetooth/rfcomm/core.c
View file @
63748aa8
...
...
@@ -46,7 +46,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#define VERSION "1.1
0
"
#define VERSION "1.1
1
"
static
int
disable_cfc
=
0
;
static
int
channel_mtu
=
-
1
;
...
...
@@ -223,19 +223,25 @@ static int rfcomm_l2sock_create(struct socket **sock)
return
err
;
}
static
inline
int
rfcomm_check_
link_mode
(
struct
rfcomm_dlc
*
d
)
static
inline
int
rfcomm_check_
security
(
struct
rfcomm_dlc
*
d
)
{
struct
sock
*
sk
=
d
->
session
->
sock
->
sk
;
__u8
auth_type
;
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
;
switch
(
d
->
sec_level
)
{
case
BT_SECURITY_HIGH
:
auth_type
=
HCI_AT_GENERAL_BONDING_MITM
;
break
;
case
BT_SECURITY_MEDIUM
:
auth_type
=
HCI_AT_GENERAL_BONDING
;
break
;
default:
auth_type
=
HCI_AT_NO_BONDING
;
break
;
}
return
0
;
return
hci_conn_security
(
l2cap_pi
(
sk
)
->
conn
->
hcon
,
d
->
sec_level
,
auth_type
);
}
/* ---- RFCOMM DLCs ---- */
...
...
@@ -388,10 +394,10 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
d
->
cfc
=
(
s
->
cfc
==
RFCOMM_CFC_UNKNOWN
)
?
0
:
s
->
cfc
;
if
(
s
->
state
==
BT_CONNECTED
)
{
if
(
rfcomm_check_link_mode
(
d
))
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
else
if
(
rfcomm_check_security
(
d
))
rfcomm_send_pn
(
s
,
1
,
d
);
else
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
}
rfcomm_dlc_set_timer
(
d
,
RFCOMM_CONN_TIMEOUT
);
...
...
@@ -421,9 +427,16 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
d
,
d
->
state
,
d
->
dlci
,
err
,
s
);
switch
(
d
->
state
)
{
case
BT_CONNECTED
:
case
BT_CONFIG
:
case
BT_CONNECT
:
case
BT_CONFIG
:
if
(
test_and_clear_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
))
{
set_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
);
rfcomm_schedule
(
RFCOMM_SCHED_AUTH
);
break
;
}
/* Fall through */
case
BT_CONNECTED
:
d
->
state
=
BT_DISCONN
;
if
(
skb_queue_empty
(
&
d
->
tx_queue
))
{
rfcomm_send_disc
(
s
,
d
->
dlci
);
...
...
@@ -434,6 +447,15 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
}
break
;
case
BT_OPEN
:
case
BT_CONNECT2
:
if
(
test_and_clear_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
))
{
set_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
);
rfcomm_schedule
(
RFCOMM_SCHED_AUTH
);
break
;
}
/* Fall through */
default:
rfcomm_dlc_clear_timer
(
d
);
...
...
@@ -636,6 +658,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
bacpy
(
&
addr
.
l2_bdaddr
,
src
);
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_psm
=
0
;
addr
.
l2_cid
=
0
;
*
err
=
kernel_bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
if
(
*
err
<
0
)
goto
failed
;
...
...
@@ -657,6 +680,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_cid
=
0
;
*
err
=
kernel_connect
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
),
O_NONBLOCK
);
if
(
*
err
==
0
||
*
err
==
-
EINPROGRESS
)
return
s
;
...
...
@@ -1162,7 +1186,7 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
return
0
;
}
static
void
rfcomm_dlc_accept
(
struct
rfcomm_dlc
*
d
)
void
rfcomm_dlc_accept
(
struct
rfcomm_dlc
*
d
)
{
struct
sock
*
sk
=
d
->
session
->
sock
->
sk
;
...
...
@@ -1175,12 +1199,31 @@ static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
d
->
state_change
(
d
,
0
);
rfcomm_dlc_unlock
(
d
);
if
(
d
->
link_mode
&
RFCOMM_LM_MASTER
)
if
(
d
->
role_switch
)
hci_conn_switch_role
(
l2cap_pi
(
sk
)
->
conn
->
hcon
,
0x00
);
rfcomm_send_msc
(
d
->
session
,
1
,
d
->
dlci
,
d
->
v24_sig
);
}
static
void
rfcomm_check_accept
(
struct
rfcomm_dlc
*
d
)
{
if
(
rfcomm_check_security
(
d
))
{
if
(
d
->
defer_setup
)
{
set_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
rfcomm_dlc_lock
(
d
);
d
->
state
=
BT_CONNECT2
;
d
->
state_change
(
d
,
0
);
rfcomm_dlc_unlock
(
d
);
}
else
rfcomm_dlc_accept
(
d
);
}
else
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
}
}
static
int
rfcomm_recv_sabm
(
struct
rfcomm_session
*
s
,
u8
dlci
)
{
struct
rfcomm_dlc
*
d
;
...
...
@@ -1203,11 +1246,7 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
if
(
d
)
{
if
(
d
->
state
==
BT_OPEN
)
{
/* DLC was previously opened by PN request */
if
(
rfcomm_check_link_mode
(
d
))
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
}
else
rfcomm_dlc_accept
(
d
);
rfcomm_check_accept
(
d
);
}
return
0
;
}
...
...
@@ -1219,11 +1258,7 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
d
->
addr
=
__addr
(
s
->
initiator
,
dlci
);
rfcomm_dlc_link
(
s
,
d
);
if
(
rfcomm_check_link_mode
(
d
))
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
}
else
rfcomm_dlc_accept
(
d
);
rfcomm_check_accept
(
d
);
}
else
{
rfcomm_send_dm
(
s
,
dlci
);
}
...
...
@@ -1637,11 +1672,12 @@ 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
;
if
(
rfcomm_check_link_mode
(
d
))
{
if
(
rfcomm_check_security
(
d
))
{
rfcomm_send_pn
(
s
,
1
,
d
);
}
else
{
set_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
}
else
rfcomm_send_pn
(
s
,
1
,
d
);
}
}
}
}
...
...
@@ -1717,11 +1753,17 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
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
);
}
else
{
if
(
d
->
defer_setup
)
{
set_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
rfcomm_dlc_lock
(
d
);
d
->
state
=
BT_CONNECT2
;
d
->
state_change
(
d
,
0
);
rfcomm_dlc_unlock
(
d
);
}
else
rfcomm_dlc_accept
(
d
);
}
continue
;
}
else
if
(
test_and_clear_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
))
{
...
...
@@ -1734,6 +1776,9 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue
;
}
if
(
test_bit
(
RFCOMM_SEC_PENDING
,
&
d
->
flags
))
continue
;
if
(
test_bit
(
RFCOMM_TX_THROTTLED
,
&
s
->
flags
))
continue
;
...
...
@@ -1876,6 +1921,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
bacpy
(
&
addr
.
l2_bdaddr
,
ba
);
addr
.
l2_family
=
AF_BLUETOOTH
;
addr
.
l2_psm
=
htobs
(
RFCOMM_PSM
);
addr
.
l2_cid
=
0
;
err
=
kernel_bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
if
(
err
<
0
)
{
BT_ERR
(
"Bind failed %d"
,
err
);
...
...
@@ -1947,42 +1993,7 @@ static int rfcomm_run(void *unused)
return
0
;
}
static
void
rfcomm_auth_cfm
(
struct
hci_conn
*
conn
,
u8
status
)
{
struct
rfcomm_session
*
s
;
struct
rfcomm_dlc
*
d
;
struct
list_head
*
p
,
*
n
;
BT_DBG
(
"conn %p status 0x%02x"
,
conn
,
status
);
s
=
rfcomm_session_get
(
&
conn
->
hdev
->
bdaddr
,
&
conn
->
dst
);
if
(
!
s
)
return
;
rfcomm_session_hold
(
s
);
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
))
&&
!
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
&&
!
status
)
continue
;
if
(
!
test_and_clear_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
))
continue
;
if
(
!
status
)
set_bit
(
RFCOMM_AUTH_ACCEPT
,
&
d
->
flags
);
else
set_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
);
}
rfcomm_session_put
(
s
);
rfcomm_schedule
(
RFCOMM_SCHED_AUTH
);
}
static
void
rfcomm_encrypt_cfm
(
struct
hci_conn
*
conn
,
u8
status
,
u8
encrypt
)
static
void
rfcomm_security_cfm
(
struct
hci_conn
*
conn
,
u8
status
,
u8
encrypt
)
{
struct
rfcomm_session
*
s
;
struct
rfcomm_dlc
*
d
;
...
...
@@ -1999,18 +2010,29 @@ 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_SEC_PENDING
,
&
d
->
flags
))
{
rfcomm_dlc_clear_timer
(
d
);
if
(
status
||
encrypt
==
0x00
)
{
__rfcomm_dlc_close
(
d
,
ECONNREFUSED
);
continue
;
}
}
if
(
d
->
state
==
BT_CONNECTED
&&
!
status
&&
encrypt
==
0x00
)
{
if
(
d
->
sec_level
==
BT_SECURITY_MEDIUM
)
{
set_bit
(
RFCOMM_SEC_PENDING
,
&
d
->
flags
);
rfcomm_dlc_set_timer
(
d
,
RFCOMM_AUTH_TIMEOUT
);
continue
;
}
else
if
(
d
->
sec_level
==
BT_SECURITY_HIGH
)
{
__rfcomm_dlc_close
(
d
,
ECONNREFUSED
);
continue
;
}
}
if
(
!
test_and_clear_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
))
continue
;
if
(
!
status
&&
encrypt
)
if
(
!
status
)
set_bit
(
RFCOMM_AUTH_ACCEPT
,
&
d
->
flags
);
else
set_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
);
...
...
@@ -2023,8 +2045,7 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
static
struct
hci_cb
rfcomm_cb
=
{
.
name
=
"RFCOMM"
,
.
auth_cfm
=
rfcomm_auth_cfm
,
.
encrypt_cfm
=
rfcomm_encrypt_cfm
.
security_cfm
=
rfcomm_security_cfm
};
static
ssize_t
rfcomm_dlc_sysfs_show
(
struct
class
*
dev
,
char
*
buf
)
...
...
net/bluetooth/rfcomm/sock.c
View file @
63748aa8
...
...
@@ -261,12 +261,19 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
if
(
parent
)
{
sk
->
sk_type
=
parent
->
sk_type
;
pi
->
link_mode
=
rfcomm_pi
(
parent
)
->
link_mode
;
pi
->
dlc
->
defer_setup
=
bt_sk
(
parent
)
->
defer_setup
;
pi
->
sec_level
=
rfcomm_pi
(
parent
)
->
sec_level
;
pi
->
role_switch
=
rfcomm_pi
(
parent
)
->
role_switch
;
}
else
{
pi
->
link_mode
=
0
;
pi
->
dlc
->
defer_setup
=
0
;
pi
->
sec_level
=
BT_SECURITY_LOW
;
pi
->
role_switch
=
0
;
}
pi
->
dlc
->
link_mode
=
pi
->
link_mode
;
pi
->
dlc
->
sec_level
=
pi
->
sec_level
;
pi
->
dlc
->
role_switch
=
pi
->
role_switch
;
}
static
struct
proto
rfcomm_proto
=
{
...
...
@@ -406,7 +413,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
;
d
->
sec_level
=
rfcomm_pi
(
sk
)
->
sec_level
;
d
->
role_switch
=
rfcomm_pi
(
sk
)
->
role_switch
;
err
=
rfcomm_dlc_open
(
d
,
&
bt_sk
(
sk
)
->
src
,
&
sa
->
rc_bdaddr
,
sa
->
rc_channel
);
if
(
!
err
)
...
...
@@ -554,6 +562,9 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct
sk_buff
*
skb
;
int
sent
=
0
;
if
(
test_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
))
return
-
ENOTCONN
;
if
(
msg
->
msg_flags
&
MSG_OOB
)
return
-
EOPNOTSUPP
;
...
...
@@ -570,8 +581,11 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
skb
=
sock_alloc_send_skb
(
sk
,
size
+
RFCOMM_SKB_RESERVE
,
msg
->
msg_flags
&
MSG_DONTWAIT
,
&
err
);
if
(
!
skb
)
if
(
!
skb
)
{
if
(
sent
==
0
)
sent
=
err
;
break
;
}
skb_reserve
(
skb
,
RFCOMM_SKB_HEAD_RESERVE
);
err
=
memcpy_fromiovec
(
skb_put
(
skb
,
size
),
msg
->
msg_iov
,
size
);
...
...
@@ -630,10 +644,16 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct
msghdr
*
msg
,
size_t
size
,
int
flags
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
rfcomm_dlc
*
d
=
rfcomm_pi
(
sk
)
->
dlc
;
int
err
=
0
;
size_t
target
,
copied
=
0
;
long
timeo
;
if
(
test_and_clear_bit
(
RFCOMM_DEFER_SETUP
,
&
d
->
flags
))
{
rfcomm_dlc_accept
(
d
);
return
0
;
}
if
(
flags
&
MSG_OOB
)
return
-
EOPNOTSUPP
;
...
...
@@ -710,7 +730,7 @@ out:
return
copied
?
:
err
;
}
static
int
rfcomm_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
optlen
)
static
int
rfcomm_sock_setsockopt
_old
(
struct
socket
*
sock
,
int
optname
,
char
__user
*
optval
,
int
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
...
...
@@ -727,7 +747,14 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
break
;
}
rfcomm_pi
(
sk
)
->
link_mode
=
opt
;
if
(
opt
&
RFCOMM_LM_AUTH
)
rfcomm_pi
(
sk
)
->
sec_level
=
BT_SECURITY_LOW
;
if
(
opt
&
RFCOMM_LM_ENCRYPT
)
rfcomm_pi
(
sk
)
->
sec_level
=
BT_SECURITY_MEDIUM
;
if
(
opt
&
RFCOMM_LM_SECURE
)
rfcomm_pi
(
sk
)
->
sec_level
=
BT_SECURITY_HIGH
;
rfcomm_pi
(
sk
)
->
role_switch
=
(
opt
&
RFCOMM_LM_MASTER
);
break
;
default:
...
...
@@ -739,12 +766,76 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
return
err
;
}
static
int
rfcomm_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
static
int
rfcomm_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
bt_security
sec
;
int
len
,
err
=
0
;
u32
opt
;
BT_DBG
(
"sk %p"
,
sk
);
if
(
level
==
SOL_RFCOMM
)
return
rfcomm_sock_setsockopt_old
(
sock
,
optname
,
optval
,
optlen
);
if
(
level
!=
SOL_BLUETOOTH
)
return
-
ENOPROTOOPT
;
lock_sock
(
sk
);
switch
(
optname
)
{
case
BT_SECURITY
:
if
(
sk
->
sk_type
!=
SOCK_STREAM
)
{
err
=
-
EINVAL
;
break
;
}
sec
.
level
=
BT_SECURITY_LOW
;
len
=
min_t
(
unsigned
int
,
sizeof
(
sec
),
optlen
);
if
(
copy_from_user
((
char
*
)
&
sec
,
optval
,
len
))
{
err
=
-
EFAULT
;
break
;
}
if
(
sec
.
level
>
BT_SECURITY_HIGH
)
{
err
=
-
EINVAL
;
break
;
}
rfcomm_pi
(
sk
)
->
sec_level
=
sec
.
level
;
break
;
case
BT_DEFER_SETUP
:
if
(
sk
->
sk_state
!=
BT_BOUND
&&
sk
->
sk_state
!=
BT_LISTEN
)
{
err
=
-
EINVAL
;
break
;
}
if
(
get_user
(
opt
,
(
u32
__user
*
)
optval
))
{
err
=
-
EFAULT
;
break
;
}
bt_sk
(
sk
)
->
defer_setup
=
opt
;
break
;
default:
err
=
-
ENOPROTOOPT
;
break
;
}
release_sock
(
sk
);
return
err
;
}
static
int
rfcomm_sock_getsockopt_old
(
struct
socket
*
sock
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sock
*
l2cap_sk
;
struct
rfcomm_conninfo
cinfo
;
int
len
,
err
=
0
;
u32
opt
;
BT_DBG
(
"sk %p"
,
sk
);
...
...
@@ -755,12 +846,32 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
switch
(
optname
)
{
case
RFCOMM_LM
:
if
(
put_user
(
rfcomm_pi
(
sk
)
->
link_mode
,
(
u32
__user
*
)
optval
))
switch
(
rfcomm_pi
(
sk
)
->
sec_level
)
{
case
BT_SECURITY_LOW
:
opt
=
RFCOMM_LM_AUTH
;
break
;
case
BT_SECURITY_MEDIUM
:
opt
=
RFCOMM_LM_AUTH
|
RFCOMM_LM_ENCRYPT
;
break
;
case
BT_SECURITY_HIGH
:
opt
=
RFCOMM_LM_AUTH
|
RFCOMM_LM_ENCRYPT
|
RFCOMM_LM_SECURE
;
break
;
default:
opt
=
0
;
break
;
}
if
(
rfcomm_pi
(
sk
)
->
role_switch
)
opt
|=
RFCOMM_LM_MASTER
;
if
(
put_user
(
opt
,
(
u32
__user
*
)
optval
))
err
=
-
EFAULT
;
break
;
case
RFCOMM_CONNINFO
:
if
(
sk
->
sk_state
!=
BT_CONNECTED
)
{
if
(
sk
->
sk_state
!=
BT_CONNECTED
&&
!
rfcomm_pi
(
sk
)
->
dlc
->
defer_setup
)
{
err
=
-
ENOTCONN
;
break
;
}
...
...
@@ -785,6 +896,60 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
return
err
;
}
static
int
rfcomm_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
bt_security
sec
;
int
len
,
err
=
0
;
BT_DBG
(
"sk %p"
,
sk
);
if
(
level
==
SOL_RFCOMM
)
return
rfcomm_sock_getsockopt_old
(
sock
,
optname
,
optval
,
optlen
);
if
(
level
!=
SOL_BLUETOOTH
)
return
-
ENOPROTOOPT
;
if
(
get_user
(
len
,
optlen
))
return
-
EFAULT
;
lock_sock
(
sk
);
switch
(
optname
)
{
case
BT_SECURITY
:
if
(
sk
->
sk_type
!=
SOCK_STREAM
)
{
err
=
-
EINVAL
;
break
;
}
sec
.
level
=
rfcomm_pi
(
sk
)
->
sec_level
;
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
sec
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
sec
,
len
))
err
=
-
EFAULT
;
break
;
case
BT_DEFER_SETUP
:
if
(
sk
->
sk_state
!=
BT_BOUND
&&
sk
->
sk_state
!=
BT_LISTEN
)
{
err
=
-
EINVAL
;
break
;
}
if
(
put_user
(
bt_sk
(
sk
)
->
defer_setup
,
(
u32
__user
*
)
optval
))
err
=
-
EFAULT
;
break
;
default:
err
=
-
ENOPROTOOPT
;
break
;
}
release_sock
(
sk
);
return
err
;
}
static
int
rfcomm_sock_ioctl
(
struct
socket
*
sock
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
sock
*
sk
__maybe_unused
=
sock
->
sk
;
...
...
@@ -888,6 +1053,10 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
done:
bh_unlock_sock
(
parent
);
if
(
bt_sk
(
parent
)
->
defer_setup
)
parent
->
sk_state_change
(
parent
);
return
result
;
}
...
...
net/bluetooth/sco.c
View file @
63748aa8
...
...
@@ -195,7 +195,7 @@ static int sco_connect(struct sock *sk)
else
type
=
SCO_LINK
;
hcon
=
hci_connect
(
hdev
,
type
,
dst
,
HCI_AT_NO_BONDING
);
hcon
=
hci_connect
(
hdev
,
type
,
dst
,
BT_SECURITY_LOW
,
HCI_AT_NO_BONDING
);
if
(
!
hcon
)
goto
done
;
...
...
@@ -668,7 +668,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
return
err
;
}
static
int
sco_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
static
int
sco_sock_getsockopt
_old
(
struct
socket
*
sock
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
struct
sco_options
opts
;
...
...
@@ -723,6 +723,31 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
return
err
;
}
static
int
sco_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
len
,
err
=
0
;
BT_DBG
(
"sk %p"
,
sk
);
if
(
level
==
SOL_SCO
)
return
sco_sock_getsockopt_old
(
sock
,
optname
,
optval
,
optlen
);
if
(
get_user
(
len
,
optlen
))
return
-
EFAULT
;
lock_sock
(
sk
);
switch
(
optname
)
{
default:
err
=
-
ENOPROTOOPT
;
break
;
}
release_sock
(
sk
);
return
err
;
}
static
int
sco_sock_release
(
struct
socket
*
sock
)
{
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -832,10 +857,30 @@ done:
/* ----- SCO interface with lower layer (HCI) ----- */
static
int
sco_connect_ind
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
__u8
type
)
{
register
struct
sock
*
sk
;
struct
hlist_node
*
node
;
int
lm
=
0
;
if
(
type
!=
SCO_LINK
&&
type
!=
ESCO_LINK
)
return
0
;
BT_DBG
(
"hdev %s, bdaddr %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
/* Always accept connection */
return
HCI_LM_ACCEPT
;
/* Find listening sockets */
read_lock
(
&
sco_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
sco_sk_list
.
head
)
{
if
(
sk
->
sk_state
!=
BT_LISTEN
)
continue
;
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
&
hdev
->
bdaddr
)
||
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
BDADDR_ANY
))
{
lm
|=
HCI_LM_ACCEPT
;
break
;
}
}
read_unlock
(
&
sco_sk_list
.
lock
);
return
lm
;
}
static
int
sco_connect_cfm
(
struct
hci_conn
*
hcon
,
__u8
status
)
...
...
@@ -857,7 +902,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
return
0
;
}
static
int
sco_disconn_
ind
(
struct
hci_conn
*
hcon
,
__u8
reason
)
static
int
sco_disconn_
cfm
(
struct
hci_conn
*
hcon
,
__u8
reason
)
{
BT_DBG
(
"hcon %p reason %d"
,
hcon
,
reason
);
...
...
@@ -940,7 +985,7 @@ static struct hci_proto sco_hci_proto = {
.
id
=
HCI_PROTO_SCO
,
.
connect_ind
=
sco_connect_ind
,
.
connect_cfm
=
sco_connect_cfm
,
.
disconn_
ind
=
sco_disconn_ind
,
.
disconn_
cfm
=
sco_disconn_cfm
,
.
recv_scodata
=
sco_recv_scodata
};
...
...
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