Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
dee04cac
Commit
dee04cac
authored
Apr 29, 2011
by
John W. Linville
Browse files
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
parents
ce6cac88
7cbc9bd9
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
include/net/bluetooth/hci.h
View file @
dee04cac
...
...
@@ -246,6 +246,15 @@ enum {
#define HCI_AT_GENERAL_BONDING 0x04
#define HCI_AT_GENERAL_BONDING_MITM 0x05
/* Link Key types */
#define HCI_LK_COMBINATION 0x00
#define HCI_LK_LOCAL_UNIT 0x01
#define HCI_LK_REMOTE_UNIT 0x02
#define HCI_LK_DEBUG_COMBINATION 0x03
#define HCI_LK_UNAUTH_COMBINATION 0x04
#define HCI_LK_AUTH_COMBINATION 0x05
#define HCI_LK_CHANGED_COMBINATION 0x06
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
...
...
include/net/bluetooth/hci_core.h
View file @
dee04cac
...
...
@@ -126,6 +126,8 @@ struct hci_dev {
__u16
sniff_min_interval
;
__u16
sniff_max_interval
;
unsigned
int
auto_accept_delay
;
unsigned
long
quirks
;
atomic_t
cmd_cnt
;
...
...
@@ -226,6 +228,7 @@ struct hci_conn {
__u16
pkt_type
;
__u16
link_policy
;
__u32
link_mode
;
__u8
key_type
;
__u8
auth_type
;
__u8
sec_level
;
__u8
pending_sec_level
;
...
...
@@ -245,6 +248,7 @@ struct hci_conn {
struct
timer_list
disc_timer
;
struct
timer_list
idle_timer
;
struct
timer_list
auto_accept_timer
;
struct
work_struct
work_add
;
struct
work_struct
work_del
;
...
...
@@ -511,8 +515,8 @@ int hci_uuids_clear(struct hci_dev *hdev);
int
hci_link_keys_clear
(
struct
hci_dev
*
hdev
);
struct
link_key
*
hci_find_link_key
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
int
hci_add_link_key
(
struct
hci_dev
*
hdev
,
int
new_key
,
bdaddr_t
*
bdaddr
,
u8
*
key
,
u8
type
,
u8
pin_len
);
int
hci_add_link_key
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
conn
,
int
new_key
,
bdaddr_t
*
bdaddr
,
u8
*
val
,
u8
type
,
u8
pin_len
);
int
hci_remove_link_key
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
int
hci_remote_oob_data_clear
(
struct
hci_dev
*
hdev
);
...
...
@@ -771,15 +775,16 @@ int mgmt_index_removed(u16 index);
int
mgmt_powered
(
u16
index
,
u8
powered
);
int
mgmt_discoverable
(
u16
index
,
u8
discoverable
);
int
mgmt_connectable
(
u16
index
,
u8
connectable
);
int
mgmt_new_key
(
u16
index
,
struct
link_key
*
key
,
u8
old_key_type
);
int
mgmt_new_key
(
u16
index
,
struct
link_key
*
key
,
u8
persistent
);
int
mgmt_connected
(
u16
index
,
bdaddr_t
*
bdaddr
);
int
mgmt_disconnected
(
u16
index
,
bdaddr_t
*
bdaddr
);
int
mgmt_disconnect_failed
(
u16
index
);
int
mgmt_connect_failed
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_pin_code_request
(
u16
index
,
bdaddr_t
*
bdaddr
);
int
mgmt_pin_code_request
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
secure
);
int
mgmt_pin_code_reply_complete
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_pin_code_neg_reply_complete
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_user_confirm_request
(
u16
index
,
bdaddr_t
*
bdaddr
,
__le32
value
);
int
mgmt_user_confirm_request
(
u16
index
,
bdaddr_t
*
bdaddr
,
__le32
value
,
u8
confirm_hint
);
int
mgmt_user_confirm_reply_complete
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_user_confirm_neg_reply_complete
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
...
...
@@ -790,6 +795,7 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
int
mgmt_device_found
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
*
dev_class
,
s8
rssi
,
u8
*
eir
);
int
mgmt_remote_name
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
*
name
);
int
mgmt_discovering
(
u16
index
,
u8
discovering
);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
...
...
include/net/bluetooth/l2cap.h
View file @
dee04cac
...
...
@@ -284,6 +284,25 @@ struct srej_list {
struct
l2cap_chan
{
struct
sock
*
sk
;
struct
l2cap_conn
*
conn
;
__le16
psm
;
__u16
dcid
;
__u16
scid
;
__u16
imtu
;
__u16
omtu
;
__u16
flush_to
;
__u8
mode
;
__le16
sport
;
__u8
sec_level
;
__u8
role_switch
;
__u8
force_reliable
;
__u8
flushable
;
__u8
ident
;
__u8
conf_req
[
64
];
...
...
@@ -291,6 +310,15 @@ struct l2cap_chan {
__u8
num_conf_req
;
__u8
num_conf_rsp
;
__u8
fcs
;
__u8
tx_win
;
__u8
max_tx
;
__u16
retrans_timeout
;
__u16
monitor_timeout
;
__u16
mps
;
__u8
conf_state
;
__u16
conn_state
;
__u8
next_tx_seq
;
...
...
@@ -360,32 +388,6 @@ struct l2cap_conn {
struct
l2cap_pinfo
{
struct
bt_sock
bt
;
__le16
psm
;
__u16
dcid
;
__u16
scid
;
__u16
imtu
;
__u16
omtu
;
__u16
flush_to
;
__u8
mode
;
__u8
fcs
;
__u8
sec_level
;
__u8
role_switch
;
__u8
force_reliable
;
__u8
flushable
;
__u8
conf_state
;
__u8
tx_win
;
__u8
max_tx
;
__u16
retrans_timeout
;
__u16
monitor_timeout
;
__u16
mps
;
__le16
sport
;
struct
l2cap_conn
*
conn
;
struct
l2cap_chan
*
chan
;
};
...
...
@@ -439,21 +441,20 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
extern
int
disable_ertm
;
extern
const
struct
proto_ops
l2cap_sock_ops
;
extern
struct
bt_sock_list
l2cap_sk_list
;
int
l2cap_init_sockets
(
void
);
void
l2cap_cleanup_sockets
(
void
);
void
l2cap_send_cmd
(
struct
l2cap_conn
*
conn
,
u8
ident
,
u8
code
,
u16
len
,
void
*
data
);
void
__l2cap_connect_rsp_defer
(
struct
sock
*
sk
);
void
__l2cap_connect_rsp_defer
(
struct
l2cap_chan
*
chan
);
int
__l2cap_wait_ack
(
struct
sock
*
sk
);
struct
sk_buff
*
l2cap_create_connless_pdu
(
struct
sock
*
sk
,
struct
msghdr
*
msg
,
size_t
len
);
struct
sk_buff
*
l2cap_create_basic_pdu
(
struct
sock
*
sk
,
struct
msghdr
*
msg
,
size_t
len
);
struct
sk_buff
*
l2cap_create_iframe_pdu
(
struct
sock
*
sk
,
struct
msghdr
*
msg
,
size_t
len
,
u16
control
,
u16
sdulen
);
struct
sk_buff
*
l2cap_create_connless_pdu
(
struct
l2cap_chan
*
chan
,
struct
msghdr
*
msg
,
size_t
len
);
struct
sk_buff
*
l2cap_create_basic_pdu
(
struct
l2cap_chan
*
chan
,
struct
msghdr
*
msg
,
size_t
len
);
struct
sk_buff
*
l2cap_create_iframe_pdu
(
struct
l2cap_chan
*
chan
,
struct
msghdr
*
msg
,
size_t
len
,
u16
control
,
u16
sdulen
);
int
l2cap_sar_segment_sdu
(
struct
l2cap_chan
*
chan
,
struct
msghdr
*
msg
,
size_t
len
);
void
l2cap_do_send
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
void
l2cap_do_send
(
struct
l2cap_chan
*
chan
,
struct
sk_buff
*
skb
);
void
l2cap_streaming_send
(
struct
l2cap_chan
*
chan
);
int
l2cap_ertm_send
(
struct
l2cap_chan
*
chan
);
...
...
@@ -465,7 +466,9 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct
sock
*
l2cap_sock_alloc
(
struct
net
*
net
,
struct
socket
*
sock
,
int
proto
,
gfp_t
prio
);
void
l2cap_send_disconn_req
(
struct
l2cap_conn
*
conn
,
struct
l2cap_chan
*
chan
,
int
err
);
struct
l2cap_chan
*
l2cap_chan_alloc
(
struct
sock
*
sk
);
void
l2cap_chan_del
(
struct
l2cap_chan
*
chan
,
int
err
);
int
l2cap_do_connect
(
struct
sock
*
sk
);
void
l2cap_chan_free
(
struct
l2cap_chan
*
chan
);
int
l2cap_chan_connect
(
struct
l2cap_chan
*
chan
);
#endif
/* __L2CAP_H */
include/net/bluetooth/mgmt.h
View file @
dee04cac
...
...
@@ -195,6 +195,10 @@ struct mgmt_cp_remove_remote_oob_data {
bdaddr_t
bdaddr
;
}
__packed
;
#define MGMT_OP_START_DISCOVERY 0x001B
#define MGMT_OP_STOP_DISCOVERY 0x001C
#define MGMT_EV_CMD_COMPLETE 0x0001
struct
mgmt_ev_cmd_complete
{
__le16
opcode
;
...
...
@@ -226,8 +230,8 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct
mgmt_ev_new_key
{
__u8
store_hint
;
struct
mgmt_key_info
key
;
__u8
old_key_type
;
}
__packed
;
#define MGMT_EV_CONNECTED 0x000B
...
...
@@ -249,11 +253,13 @@ struct mgmt_ev_connect_failed {
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct
mgmt_ev_pin_code_request
{
bdaddr_t
bdaddr
;
__u8
secure
;
}
__packed
;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct
mgmt_ev_user_confirm_request
{
bdaddr_t
bdaddr
;
__u8
confirm_hint
;
__le32
value
;
}
__packed
;
...
...
@@ -281,3 +287,5 @@ struct mgmt_ev_remote_name {
bdaddr_t
bdaddr
;
__u8
name
[
MGMT_MAX_NAME_LENGTH
];
}
__packed
;
#define MGMT_EV_DISCOVERING 0x0014
net/bluetooth/cmtp/core.c
View file @
dee04cac
...
...
@@ -346,7 +346,8 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
bacpy
(
&
session
->
bdaddr
,
&
bt_sk
(
sock
->
sk
)
->
dst
);
session
->
mtu
=
min_t
(
uint
,
l2cap_pi
(
sock
->
sk
)
->
omtu
,
l2cap_pi
(
sock
->
sk
)
->
imtu
);
session
->
mtu
=
min_t
(
uint
,
l2cap_pi
(
sock
->
sk
)
->
chan
->
omtu
,
l2cap_pi
(
sock
->
sk
)
->
chan
->
imtu
);
BT_DBG
(
"mtu %d"
,
session
->
mtu
);
...
...
net/bluetooth/hci_conn.c
View file @
dee04cac
...
...
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
hci_conn_enter_sniff_mode
(
conn
);
}
static
void
hci_conn_auto_accept
(
unsigned
long
arg
)
{
struct
hci_conn
*
conn
=
(
void
*
)
arg
;
struct
hci_dev
*
hdev
=
conn
->
hdev
;
hci_dev_lock
(
hdev
);
hci_send_cmd
(
hdev
,
HCI_OP_USER_CONFIRM_REPLY
,
sizeof
(
conn
->
dst
),
&
conn
->
dst
);
hci_dev_unlock
(
hdev
);
}
struct
hci_conn
*
hci_conn_add
(
struct
hci_dev
*
hdev
,
int
type
,
bdaddr_t
*
dst
)
{
struct
hci_conn
*
conn
;
...
...
@@ -287,6 +300,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn
->
auth_type
=
HCI_AT_GENERAL_BONDING
;
conn
->
io_capability
=
hdev
->
io_capability
;
conn
->
remote_auth
=
0xff
;
conn
->
key_type
=
0xff
;
conn
->
power_save
=
1
;
conn
->
disc_timeout
=
HCI_DISCONN_TIMEOUT
;
...
...
@@ -311,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
setup_timer
(
&
conn
->
disc_timer
,
hci_conn_timeout
,
(
unsigned
long
)
conn
);
setup_timer
(
&
conn
->
idle_timer
,
hci_conn_idle
,
(
unsigned
long
)
conn
);
setup_timer
(
&
conn
->
auto_accept_timer
,
hci_conn_auto_accept
,
(
unsigned
long
)
conn
);
atomic_set
(
&
conn
->
refcnt
,
0
);
...
...
@@ -341,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
del_timer
(
&
conn
->
disc_timer
);
del_timer
(
&
conn
->
auto_accept_timer
);
if
(
conn
->
type
==
ACL_LINK
)
{
struct
hci_conn
*
sco
=
conn
->
link
;
if
(
sco
)
...
...
@@ -535,32 +553,72 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
return
0
;
}
/* Encrypt the the link */
static
void
hci_conn_encrypt
(
struct
hci_conn
*
conn
)
{
BT_DBG
(
"conn %p"
,
conn
);
if
(
!
test_and_set_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
{
struct
hci_cp_set_conn_encrypt
cp
;
cp
.
handle
=
cpu_to_le16
(
conn
->
handle
);
cp
.
encrypt
=
0x01
;
hci_send_cmd
(
conn
->
hdev
,
HCI_OP_SET_CONN_ENCRYPT
,
sizeof
(
cp
),
&
cp
);
}
}
/* Enable security */
int
hci_conn_security
(
struct
hci_conn
*
conn
,
__u8
sec_level
,
__u8
auth_type
)
{
BT_DBG
(
"conn %p"
,
conn
);
/* For sdp we don't need the link key. */
if
(
sec_level
==
BT_SECURITY_SDP
)
return
1
;
/* For non 2.1 devices and low security level we don't need the link
key. */
if
(
sec_level
==
BT_SECURITY_LOW
&&
(
!
conn
->
ssp_mode
||
!
conn
->
hdev
->
ssp_mode
))
return
1
;
if
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
return
hci_conn_auth
(
conn
,
sec_level
,
auth_type
);
/* For other security levels we need the link key. */
if
(
!
(
conn
->
link_mode
&
HCI_LM_AUTH
))
goto
auth
;
/* An authenticated combination key has sufficient security for any
security level. */
if
(
conn
->
key_type
==
HCI_LK_AUTH_COMBINATION
)
goto
encrypt
;
/* An unauthenticated combination key has sufficient security for
security level 1 and 2. */
if
(
conn
->
key_type
==
HCI_LK_UNAUTH_COMBINATION
&&
(
sec_level
==
BT_SECURITY_MEDIUM
||
sec_level
==
BT_SECURITY_LOW
))
goto
encrypt
;
/* A combination key has always sufficient security for the security
levels 1 or 2. High security level requires the combination key
is generated using maximum PIN code length (16).
For pre 2.1 units. */
if
(
conn
->
key_type
==
HCI_LK_COMBINATION
&&
(
sec_level
!=
BT_SECURITY_HIGH
||
conn
->
pin_length
==
16
))
goto
encrypt
;
auth:
if
(
test_and_set_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
pend
))
return
0
;
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
);
}
hci_conn_auth
(
conn
,
sec_level
,
auth_type
);
return
0
;
encrypt:
if
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
return
1
;
hci_conn_encrypt
(
conn
);
return
0
;
}
EXPORT_SYMBOL
(
hci_conn_security
);
...
...
net/bluetooth/hci_core.c
View file @
dee04cac
...
...
@@ -1020,18 +1020,54 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return
NULL
;
}
int
hci_add_link_key
(
struct
hci_dev
*
hdev
,
int
new_key
,
bdaddr_t
*
bdaddr
,
u8
*
val
,
u8
type
,
u8
pin_len
)
static
int
hci_persistent_key
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
conn
,
u8
key_type
,
u8
old_key_type
)
{
/* Legacy key */
if
(
key_type
<
0x03
)
return
1
;
/* Debug keys are insecure so don't store them persistently */
if
(
key_type
==
HCI_LK_DEBUG_COMBINATION
)
return
0
;
/* Changed combination key and there's no previous one */
if
(
key_type
==
HCI_LK_CHANGED_COMBINATION
&&
old_key_type
==
0xff
)
return
0
;
/* Security mode 3 case */
if
(
!
conn
)
return
1
;
/* Neither local nor remote side had no-bonding as requirement */
if
(
conn
->
auth_type
>
0x01
&&
conn
->
remote_auth
>
0x01
)
return
1
;
/* Local side had dedicated bonding as requirement */
if
(
conn
->
auth_type
==
0x02
||
conn
->
auth_type
==
0x03
)
return
1
;
/* Remote side had dedicated bonding as requirement */
if
(
conn
->
remote_auth
==
0x02
||
conn
->
remote_auth
==
0x03
)
return
1
;
/* If none of the above criteria match, then don't store the key
* persistently */
return
0
;
}
int
hci_add_link_key
(
struct
hci_dev
*
hdev
,
struct
hci_conn
*
conn
,
int
new_key
,
bdaddr_t
*
bdaddr
,
u8
*
val
,
u8
type
,
u8
pin_len
)
{
struct
link_key
*
key
,
*
old_key
;
u8
old_key_type
;
u8
old_key_type
,
persistent
;
old_key
=
hci_find_link_key
(
hdev
,
bdaddr
);
if
(
old_key
)
{
old_key_type
=
old_key
->
type
;
key
=
old_key
;
}
else
{
old_key_type
=
0xff
;
old_key_type
=
conn
?
conn
->
key_type
:
0xff
;
key
=
kzalloc
(
sizeof
(
*
key
),
GFP_ATOMIC
);
if
(
!
key
)
return
-
ENOMEM
;
...
...
@@ -1040,16 +1076,37 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
BT_DBG
(
"%s key for %s type %u"
,
hdev
->
name
,
batostr
(
bdaddr
),
type
);
/* Some buggy controller combinations generate a changed
* combination key for legacy pairing even when there's no
* previous key */
if
(
type
==
HCI_LK_CHANGED_COMBINATION
&&
(
!
conn
||
conn
->
remote_auth
==
0xff
)
&&
old_key_type
==
0xff
)
{
type
=
HCI_LK_COMBINATION
;
if
(
conn
)
conn
->
key_type
=
type
;
}
bacpy
(
&
key
->
bdaddr
,
bdaddr
);
memcpy
(
key
->
val
,
val
,
16
);
key
->
type
=
type
;
key
->
pin_len
=
pin_len
;
if
(
new_key
)
mgmt_new_key
(
hdev
->
id
,
key
,
old_key_type
);
if
(
type
==
0x06
)
if
(
type
==
HCI_LK_CHANGED_COMBINATION
)
key
->
type
=
old_key_type
;
else
key
->
type
=
type
;
if
(
!
new_key
)
return
0
;
persistent
=
hci_persistent_key
(
hdev
,
conn
,
type
,
old_key_type
);
mgmt_new_key
(
hdev
->
id
,
key
,
persistent
);
if
(
!
persistent
)
{
list_del
(
&
key
->
list
);
kfree
(
key
);
}
return
0
;
}
...
...
net/bluetooth/hci_event.c
View file @
dee04cac
...
...
@@ -56,7 +56,9 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
if
(
status
)
return
;
clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
)
&&
test_and_clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
mgmt_discovering
(
hdev
->
id
,
0
);
hci_req_complete
(
hdev
,
HCI_OP_INQUIRY_CANCEL
,
status
);
...
...
@@ -72,7 +74,9 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
if
(
status
)
return
;
clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
)
&&
test_and_clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
mgmt_discovering
(
hdev
->
id
,
0
);
hci_conn_check_pending
(
hdev
);
}
...
...
@@ -841,10 +845,14 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
if
(
status
)
{
hci_req_complete
(
hdev
,
HCI_OP_INQUIRY
,
status
);
hci_conn_check_pending
(
hdev
);
}
else
set_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
return
;
}
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
)
&&
!
test_and_set_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
mgmt_discovering
(
hdev
->
id
,
1
);
}
static
inline
void
hci_cs_create_conn
(
struct
hci_dev
*
hdev
,
__u8
status
)
...
...
@@ -1013,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
cp
->
bdaddr
);
if
(
conn
&&
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
if
(
!
conn
)
goto
unlock
;
if
(
!
hci_outgoing_auth_needed
(
hdev
,
conn
))
goto
unlock
;
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
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
unlock:
hci_dev_unlock
(
hdev
);
}
...
...
@@ -1208,7 +1223,9 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG
(
"%s status %d"
,
hdev
->
name
,
status
);
clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
)
&&
test_and_clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
mgmt_discovering
(
hdev
->
id
,
0
);
hci_req_complete
(
hdev
,
HCI_OP_INQUIRY
,
status
);
...
...
@@ -1228,6 +1245,12 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock
(
hdev
);
if
(
!
test_and_set_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
{
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_discovering
(
hdev
->
id
,
1
);
}
for
(;
num_rsp
;
num_rsp
--
,
info
++
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
...
...
@@ -1443,7 +1466,6 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn
->
sec_level
=
conn
->
pending_sec_level
;
}
else
{
mgmt_auth_failed
(
hdev
->
id
,
&
conn
->
dst
,
ev
->
status
);
conn
->
sec_level
=
BT_SECURITY_LOW
;
}
clear_bit
(
HCI_CONN_AUTH_PEND
,
&
conn
->
pend
);
...
...
@@ -1501,12 +1523,19 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
mgmt_remote_name
(
hdev
->
id
,
&
ev
->
bdaddr
,
ev
->
name
);
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
ev
->
bdaddr
);
if
(
conn
&&
hci_outgoing_auth_needed
(
hdev
,
conn
))
{
if
(
!
conn
)
goto
unlock
;
if
(
!
hci_outgoing_auth_needed
(
hdev
,
conn
))
goto
unlock
;
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
(
hdev
,
HCI_OP_AUTH_REQUESTED
,
sizeof
(
cp
),
&
cp
);
}
unlock:
hci_dev_unlock
(
hdev
);
}
...
...
@@ -2006,9 +2035,16 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
if
(
!
test_bit
(
HCI_PAIRABLE
,
&
hdev
->
flags
))
hci_send_cmd
(
hdev
,
HCI_OP_PIN_CODE_NEG_REPLY
,
sizeof
(
ev
->
bdaddr
),
&
ev
->
bdaddr
);
else
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
{
u8
secure
;
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_pin_code_request
(
hdev
->
id
,
&
ev
->
bdaddr
);
if
(
conn
->
pending_sec_level
==
BT_SECURITY_HIGH
)
secure
=
1
;
else
secure
=
0
;
mgmt_pin_code_request
(
hdev
->
id
,
&
ev
->
bdaddr
,
secure
);
}
hci_dev_unlock
(
hdev
);
}
...
...
@@ -2037,17 +2073,30 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG
(
"%s found key type %u for %s"
,
hdev
->
name
,
key
->
type
,
batostr
(
&
ev
->
bdaddr
));
if
(
!
test_bit
(
HCI_DEBUG_KEYS
,
&
hdev
->
flags
)
&&
key
->
type
==
0x03
)
{
if
(
!
test_bit
(
HCI_DEBUG_KEYS
,
&
hdev
->
flags
)
&&
key
->
type
==
HCI_LK_DEBUG_COMBINATION
)
{
BT_DBG
(
"%s ignoring debug key"
,
hdev
->
name
);
goto
not_found
;
}
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
ev
->
bdaddr
);
if
(
conn
)
{
if
(
key
->
type
==
HCI_LK_UNAUTH_COMBINATION
&&
conn
->
auth_type
!=
0xff
&&