Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
15cb3096
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
15cb3096
编写于
5月 12, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
上级
4daf50f2
55183d06
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
180 addition
and
124 deletion
+180
-124
drivers/bluetooth/ath3k.c
drivers/bluetooth/ath3k.c
+1
-0
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+1
-0
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+1
-0
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+6
-3
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+17
-0
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+4
-1
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_core.c
+133
-60
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_sock.c
+13
-59
net/bluetooth/mgmt.c
net/bluetooth/mgmt.c
+3
-0
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+1
-1
未找到文件。
drivers/bluetooth/ath3k.c
浏览文件 @
15cb3096
...
...
@@ -62,6 +62,7 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 with sflash firmware*/
{
USB_DEVICE
(
0x0CF3
,
0x3002
)
},
{
USB_DEVICE
(
0x13d3
,
0x3304
)
},
/* Atheros AR9285 Malbec with sflash firmware */
{
USB_DEVICE
(
0x03F0
,
0x311D
)
},
...
...
drivers/bluetooth/btusb.c
浏览文件 @
15cb3096
...
...
@@ -104,6 +104,7 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */
{
USB_DEVICE
(
0x0cf3
,
0x3002
),
.
driver_info
=
BTUSB_IGNORE
},
{
USB_DEVICE
(
0x13d3
,
0x3304
),
.
driver_info
=
BTUSB_IGNORE
},
/* Atheros AR9285 Malbec with sflash firmware */
{
USB_DEVICE
(
0x03f0
,
0x311d
),
.
driver_info
=
BTUSB_IGNORE
},
...
...
include/net/bluetooth/hci_core.h
浏览文件 @
15cb3096
...
...
@@ -422,6 +422,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
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_check_secure
(
struct
hci_conn
*
conn
,
__u8
sec_level
);
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
,
__u8
role
);
...
...
include/net/bluetooth/l2cap.h
浏览文件 @
15cb3096
...
...
@@ -350,6 +350,7 @@ struct l2cap_chan {
struct
list_head
srej_l
;
struct
list_head
list
;
struct
list_head
global_l
;
};
struct
l2cap_conn
{
...
...
@@ -441,7 +442,6 @@ 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
struct
bt_sock_list
l2cap_sk_list
;
int
l2cap_init_sockets
(
void
);
void
l2cap_cleanup_sockets
(
void
);
...
...
@@ -458,6 +458,9 @@ 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
);
int
l2cap_add_psm
(
struct
l2cap_chan
*
chan
,
bdaddr_t
*
src
,
__le16
psm
);
int
l2cap_add_scid
(
struct
l2cap_chan
*
chan
,
__u16
scid
);
void
l2cap_sock_set_timer
(
struct
sock
*
sk
,
long
timeout
);
void
l2cap_sock_clear_timer
(
struct
sock
*
sk
);
void
__l2cap_sock_close
(
struct
sock
*
sk
,
int
reason
);
...
...
@@ -466,9 +469,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
);
struct
l2cap_chan
*
l2cap_chan_
create
(
struct
sock
*
sk
);
void
l2cap_chan_del
(
struct
l2cap_chan
*
chan
,
int
err
);
void
l2cap_chan_
free
(
struct
l2cap_chan
*
chan
);
void
l2cap_chan_
destroy
(
struct
l2cap_chan
*
chan
);
int
l2cap_chan_connect
(
struct
l2cap_chan
*
chan
);
#endif
/* __L2CAP_H */
net/bluetooth/hci_conn.c
浏览文件 @
15cb3096
...
...
@@ -623,6 +623,23 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
}
EXPORT_SYMBOL
(
hci_conn_security
);
/* Check secure link requirement */
int
hci_conn_check_secure
(
struct
hci_conn
*
conn
,
__u8
sec_level
)
{
BT_DBG
(
"conn %p"
,
conn
);
if
(
sec_level
!=
BT_SECURITY_HIGH
)
return
1
;
/* Accept if non-secure is required */
if
(
conn
->
key_type
==
HCI_LK_AUTH_COMBINATION
||
(
conn
->
key_type
==
HCI_LK_COMBINATION
&&
conn
->
pin_length
==
16
))
return
1
;
return
0
;
/* Reject not secure link */
}
EXPORT_SYMBOL
(
hci_conn_check_secure
);
/* Change link key */
int
hci_conn_change_link_key
(
struct
hci_conn
*
conn
)
{
...
...
net/bluetooth/hci_event.c
浏览文件 @
15cb3096
...
...
@@ -1440,7 +1440,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
conn
->
state
=
BT_CLOSED
;
if
(
conn
->
type
==
ACL_LINK
)
if
(
conn
->
type
==
ACL_LINK
||
conn
->
type
==
LE_LINK
)
mgmt_disconnected
(
hdev
->
id
,
&
conn
->
dst
);
hci_proto_disconn_cfm
(
conn
,
ev
->
reason
);
...
...
@@ -2659,12 +2659,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
}
if
(
ev
->
status
)
{
mgmt_connect_failed
(
hdev
->
id
,
&
ev
->
bdaddr
,
ev
->
status
);
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
conn
->
state
=
BT_CLOSED
;
hci_conn_del
(
conn
);
goto
unlock
;
}
mgmt_connected
(
hdev
->
id
,
&
ev
->
bdaddr
);
conn
->
handle
=
__le16_to_cpu
(
ev
->
handle
);
conn
->
state
=
BT_CONNECTED
;
...
...
net/bluetooth/l2cap_core.c
浏览文件 @
15cb3096
...
...
@@ -62,9 +62,8 @@ static u8 l2cap_fixed_chan[8] = { 0x02, };
static
struct
workqueue_struct
*
_busy_wq
;
struct
bt_sock_list
l2cap_sk_list
=
{
.
lock
=
__RW_LOCK_UNLOCKED
(
l2cap_sk_list
.
lock
)
};
LIST_HEAD
(
chan_list
);
DEFINE_RWLOCK
(
chan_list_lock
);
static
void
l2cap_busy_work
(
struct
work_struct
*
work
);
...
...
@@ -135,6 +134,64 @@ static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn
return
c
;
}
static
struct
l2cap_chan
*
__l2cap_global_chan_by_addr
(
__le16
psm
,
bdaddr_t
*
src
)
{
struct
l2cap_chan
*
c
;
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
if
(
c
->
sport
==
psm
&&
!
bacmp
(
&
bt_sk
(
c
->
sk
)
->
src
,
src
))
goto
found
;
}
c
=
NULL
;
found:
return
c
;
}
int
l2cap_add_psm
(
struct
l2cap_chan
*
chan
,
bdaddr_t
*
src
,
__le16
psm
)
{
int
err
;
write_lock_bh
(
&
chan_list_lock
);
if
(
psm
&&
__l2cap_global_chan_by_addr
(
psm
,
src
))
{
err
=
-
EADDRINUSE
;
goto
done
;
}
if
(
psm
)
{
chan
->
psm
=
psm
;
chan
->
sport
=
psm
;
err
=
0
;
}
else
{
u16
p
;
err
=
-
EINVAL
;
for
(
p
=
0x1001
;
p
<
0x1100
;
p
+=
2
)
if
(
!
__l2cap_global_chan_by_addr
(
cpu_to_le16
(
p
),
src
))
{
chan
->
psm
=
cpu_to_le16
(
p
);
chan
->
sport
=
cpu_to_le16
(
p
);
err
=
0
;
break
;
}
}
done:
write_unlock_bh
(
&
chan_list_lock
);
return
err
;
}
int
l2cap_add_scid
(
struct
l2cap_chan
*
chan
,
__u16
scid
)
{
write_lock_bh
(
&
chan_list_lock
);
chan
->
scid
=
scid
;
write_unlock_bh
(
&
chan_list_lock
);
return
0
;
}
static
u16
l2cap_alloc_cid
(
struct
l2cap_conn
*
conn
)
{
u16
cid
=
L2CAP_CID_DYN_START
;
...
...
@@ -147,7 +204,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
return
0
;
}
struct
l2cap_chan
*
l2cap_chan_
alloc
(
struct
sock
*
sk
)
struct
l2cap_chan
*
l2cap_chan_
create
(
struct
sock
*
sk
)
{
struct
l2cap_chan
*
chan
;
...
...
@@ -157,11 +214,19 @@ struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
chan
->
sk
=
sk
;
write_lock_bh
(
&
chan_list_lock
);
list_add
(
&
chan
->
global_l
,
&
chan_list
);
write_unlock_bh
(
&
chan_list_lock
);
return
chan
;
}
void
l2cap_chan_
free
(
struct
l2cap_chan
*
chan
)
void
l2cap_chan_
destroy
(
struct
l2cap_chan
*
chan
)
{
write_lock_bh
(
&
chan_list_lock
);
list_del
(
&
chan
->
global_l
);
write_unlock_bh
(
&
chan_list_lock
);
kfree
(
chan
);
}
...
...
@@ -591,48 +656,51 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
/* Find socket with cid and source bdaddr.
* Returns closest match, locked.
*/
static
struct
sock
*
l2cap_get_sock
_by_scid
(
int
state
,
__le16
cid
,
bdaddr_t
*
src
)
static
struct
l2cap_chan
*
l2cap_global_chan
_by_scid
(
int
state
,
__le16
cid
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
struct
l2cap_chan
*
c
,
*
c1
=
NULL
;
read_lock
(
&
l2cap_sk_list
.
lock
);
read_lock
(
&
chan_list_
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
struct
l2cap_chan
*
chan
=
l2cap_pi
(
sk
)
->
chan
;
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
struct
sock
*
sk
=
c
->
sk
;
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
if
(
c
han
->
scid
==
cid
)
{
if
(
c
->
scid
==
cid
)
{
/* Exact match. */
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
break
;
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
{
read_unlock
(
&
chan_list_lock
);
return
c
;
}
/* Closest match */
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
BDADDR_ANY
))
sk1
=
sk
;
c1
=
c
;
}
}
read_unlock
(
&
l2cap_sk_list
.
lock
);
read_unlock
(
&
chan_list_
lock
);
return
node
?
sk
:
sk
1
;
return
c
1
;
}
static
void
l2cap_le_conn_ready
(
struct
l2cap_conn
*
conn
)
{
struct
sock
*
parent
,
*
sk
;
struct
l2cap_chan
*
chan
;
struct
l2cap_chan
*
chan
,
*
pchan
;
BT_DBG
(
""
);
/* Check if we have socket listening on cid */
p
arent
=
l2cap_get_sock
_by_scid
(
BT_LISTEN
,
L2CAP_CID_LE_DATA
,
p
chan
=
l2cap_global_chan
_by_scid
(
BT_LISTEN
,
L2CAP_CID_LE_DATA
,
conn
->
src
);
if
(
!
p
arent
)
if
(
!
p
chan
)
return
;
parent
=
pchan
->
sk
;
bh_lock_sock
(
parent
);
/* Check for backlog size */
...
...
@@ -645,7 +713,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
if
(
!
sk
)
goto
clean
;
chan
=
l2cap_chan_
alloc
(
sk
);
chan
=
l2cap_chan_
create
(
sk
);
if
(
!
chan
)
{
l2cap_sock_kill
(
sk
);
goto
clean
;
...
...
@@ -823,33 +891,34 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *ch
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
static
struct
sock
*
l2cap_get_sock
_by_psm
(
int
state
,
__le16
psm
,
bdaddr_t
*
src
)
static
struct
l2cap_chan
*
l2cap_global_chan
_by_psm
(
int
state
,
__le16
psm
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
=
NULL
,
*
sk1
=
NULL
;
struct
hlist_node
*
node
;
struct
l2cap_chan
*
c
,
*
c1
=
NULL
;
read_lock
(
&
l2cap_sk_list
.
lock
);
read_lock
(
&
chan_list_
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
struct
l2cap_chan
*
chan
=
l2cap_pi
(
sk
)
->
chan
;
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
struct
sock
*
sk
=
c
->
sk
;
if
(
state
&&
sk
->
sk_state
!=
state
)
continue
;
if
(
c
han
->
psm
==
psm
)
{
if
(
c
->
psm
==
psm
)
{
/* Exact match. */
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
break
;
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
{
read_unlock_bh
(
&
chan_list_lock
);
return
c
;
}
/* Closest match */
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
BDADDR_ANY
))
sk1
=
sk
;
c1
=
c
;
}
}
read_unlock
(
&
l2cap_sk_list
.
lock
);
read_unlock
(
&
chan_list_
lock
);
return
node
?
sk
:
sk
1
;
return
c
1
;
}
int
l2cap_chan_connect
(
struct
l2cap_chan
*
chan
)
...
...
@@ -2019,7 +2088,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
{
struct
l2cap_conn_req
*
req
=
(
struct
l2cap_conn_req
*
)
data
;
struct
l2cap_conn_rsp
rsp
;
struct
l2cap_chan
*
chan
=
NULL
;
struct
l2cap_chan
*
chan
=
NULL
,
*
pchan
;
struct
sock
*
parent
,
*
sk
=
NULL
;
int
result
,
status
=
L2CAP_CS_NO_INFO
;
...
...
@@ -2029,12 +2098,14 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
BT_DBG
(
"psm 0x%2.2x scid 0x%4.4x"
,
psm
,
scid
);
/* Check if we have socket listening on psm */
p
arent
=
l2cap_get_sock
_by_psm
(
BT_LISTEN
,
psm
,
conn
->
src
);
if
(
!
p
arent
)
{
p
chan
=
l2cap_global_chan
_by_psm
(
BT_LISTEN
,
psm
,
conn
->
src
);
if
(
!
p
chan
)
{
result
=
L2CAP_CR_BAD_PSM
;
goto
sendresp
;
}
parent
=
pchan
->
sk
;
bh_lock_sock
(
parent
);
/* Check if the ACL is secure enough (if not SDP) */
...
...
@@ -2057,7 +2128,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
if
(
!
sk
)
goto
response
;
chan
=
l2cap_chan_
alloc
(
sk
);
chan
=
l2cap_chan_
create
(
sk
);
if
(
!
chan
)
{
l2cap_sock_kill
(
sk
);
goto
response
;
...
...
@@ -3685,11 +3756,14 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
static
inline
int
l2cap_conless_channel
(
struct
l2cap_conn
*
conn
,
__le16
psm
,
struct
sk_buff
*
skb
)
{
struct
sock
*
sk
;
struct
l2cap_chan
*
chan
;
sk
=
l2cap_get_sock
_by_psm
(
0
,
psm
,
conn
->
src
);
if
(
!
sk
)
chan
=
l2cap_global_chan
_by_psm
(
0
,
psm
,
conn
->
src
);
if
(
!
chan
)
goto
drop
;
sk
=
chan
->
sk
;
bh_lock_sock
(
sk
);
BT_DBG
(
"sk %p, len %d"
,
sk
,
skb
->
len
);
...
...
@@ -3715,11 +3789,14 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
static
inline
int
l2cap_att_channel
(
struct
l2cap_conn
*
conn
,
__le16
cid
,
struct
sk_buff
*
skb
)
{
struct
sock
*
sk
;
struct
l2cap_chan
*
chan
;
sk
=
l2cap_get_sock
_by_scid
(
0
,
cid
,
conn
->
src
);
if
(
!
sk
)
chan
=
l2cap_global_chan
_by_scid
(
0
,
cid
,
conn
->
src
);
if
(
!
chan
)
goto
drop
;
sk
=
chan
->
sk
;
bh_lock_sock
(
sk
);
BT_DBG
(
"sk %p, len %d"
,
sk
,
skb
->
len
);
...
...
@@ -3786,8 +3863,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
static
int
l2cap_connect_ind
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
type
)
{
int
exact
=
0
,
lm1
=
0
,
lm2
=
0
;
register
struct
sock
*
sk
;
struct
hlist_node
*
node
;
struct
l2cap_chan
*
c
;
if
(
type
!=
ACL_LINK
)
return
-
EINVAL
;
...
...
@@ -3795,25 +3871,25 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
BT_DBG
(
"hdev %s, bdaddr %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
/* Find listening sockets and check their link_mode */
read_lock
(
&
l2cap_sk_list
.
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
struct
l2cap_chan
*
chan
=
l2cap_pi
(
sk
)
->
chan
;
read_lock
(
&
chan_list_
lock
);
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
struct
sock
*
sk
=
c
->
sk
;
if
(
sk
->
sk_state
!=
BT_LISTEN
)
continue
;
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
&
hdev
->
bdaddr
))
{
lm1
|=
HCI_LM_ACCEPT
;
if
(
c
han
->
role_switch
)
if
(
c
->
role_switch
)
lm1
|=
HCI_LM_MASTER
;
exact
++
;
}
else
if
(
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
BDADDR_ANY
))
{
lm2
|=
HCI_LM_ACCEPT
;
if
(
c
han
->
role_switch
)
if
(
c
->
role_switch
)
lm2
|=
HCI_LM_MASTER
;
}
}
read_unlock
(
&
l2cap_sk_list
.
lock
);
read_unlock
(
&
chan_list_
lock
);
return
exact
?
lm1
:
lm2
;
}
...
...
@@ -4066,25 +4142,22 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
static
int
l2cap_debugfs_show
(
struct
seq_file
*
f
,
void
*
p
)
{
struct
sock
*
sk
;
struct
hlist_node
*
node
;
struct
l2cap_chan
*
c
;
read_lock_bh
(
&
l2cap_sk_list
.
lock
);
read_lock_bh
(
&
chan_list_
lock
);
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
struct
l2cap_pinfo
*
pi
=
l2cap_pi
(
sk
);
struct
l2cap_chan
*
chan
=
pi
->
chan
;
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
struct
sock
*
sk
=
c
->
sk
;
seq_printf
(
f
,
"%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d
\n
"
,
batostr
(
&
bt_sk
(
sk
)
->
src
),
batostr
(
&
bt_sk
(
sk
)
->
dst
),
sk
->
sk_state
,
__le16_to_cpu
(
chan
->
psm
),
chan
->
scid
,
chan
->
dcid
,
chan
->
imtu
,
chan
->
omtu
,
chan
->
sec_level
,
chan
->
mode
);
sk
->
sk_state
,
__le16_to_cpu
(
c
->
psm
),
c
->
scid
,
c
->
dcid
,
c
->
imtu
,
c
->
omtu
,
c
->
sec_level
,
c
->
mode
);
}
read_unlock_bh
(
&
l2cap_sk_list
.
lock
);
read_unlock_bh
(
&
chan_list_
lock
);
return
0
;
}
...
...
net/bluetooth/l2cap_sock.c
浏览文件 @
15cb3096
...
...
@@ -78,22 +78,6 @@ void l2cap_sock_clear_timer(struct sock *sk)
sk_stop_timer
(
sk
,
&
sk
->
sk_timer
);
}
static
struct
sock
*
__l2cap_get_sock_by_addr
(
__le16
psm
,
bdaddr_t
*
src
)
{
struct
sock
*
sk
;
struct
hlist_node
*
node
;
sk_for_each
(
sk
,
node
,
&
l2cap_sk_list
.
head
)
{
struct
l2cap_chan
*
chan
=
l2cap_pi
(
sk
)
->
chan
;
if
(
chan
->
sport
==
psm
&&
!
bacmp
(
&
bt_sk
(
sk
)
->
src
,
src
))
goto
found
;
}
sk
=
NULL
;
found:
return
sk
;
}
static
int
l2cap_sock_bind
(
struct
socket
*
sock
,
struct
sockaddr
*
addr
,
int
alen
)
{
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -136,26 +120,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
}
}
write_lock_bh
(
&
l2cap_sk_list
.
lock
);
if
(
la
.
l2_cid
)
err
=
l2cap_add_scid
(
chan
,
la
.
l2_cid
);
else
err
=
l2cap_add_psm
(
chan
,
&
la
.
l2_bdaddr
,
la
.
l2_psm
);
if
(
la
.
l2_psm
&&
__l2cap_get_sock_by_addr
(
la
.
l2_psm
,
&
la
.
l2_bdaddr
))
{
err
=
-
EADDRINUSE
;
}
else
{
/* Save source address */
bacpy
(
&
bt_sk
(
sk
)
->
src
,
&
la
.
l2_bdaddr
);
chan
->
psm
=
la
.
l2_psm
;
chan
->
sport
=
la
.
l2_psm
;
sk
->
sk_state
=
BT_BOUND
;
if
(
__le16_to_cpu
(
la
.
l2_psm
)
==
0x0001
||
__le16_to_cpu
(
la
.
l2_psm
)
==
0x0003
)
chan
->
sec_level
=
BT_SECURITY_SDP
;
}
if
(
err
<
0
)
goto
done
;
if
(
la
.
l2_cid
)
chan
->
scid
=
la
.
l2_cid
;
if
(
__le16_to_cpu
(
la
.
l2_psm
)
==
0x0001
||
__le16_to_cpu
(
la
.
l2_psm
)
==
0x0003
)
chan
->
sec_level
=
BT_SECURITY_SDP
;
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
bacpy
(
&
bt_sk
(
sk
)
->
src
,
&
la
.
l2_bdaddr
);
sk
->
sk_state
=
BT_BOUND
;
done:
release_sock
(
sk
);
...
...
@@ -278,28 +256,6 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
goto
done
;
}
if
(
!
chan
->
psm
&&
!
chan
->
scid
)
{
bdaddr_t
*
src
=
&
bt_sk
(
sk
)
->
src
;
u16
psm
;
err
=
-
EINVAL
;
write_lock_bh
(
&
l2cap_sk_list
.
lock
);
for
(
psm
=
0x1001
;
psm
<
0x1100
;
psm
+=
2
)
if
(
!
__l2cap_get_sock_by_addr
(
cpu_to_le16
(
psm
),
src
))
{
chan
->
psm
=
cpu_to_le16
(
psm
);
chan
->
sport
=
cpu_to_le16
(
psm
);
err
=
0
;
break
;
}
write_unlock_bh
(
&
l2cap_sk_list
.
lock
);
if
(
err
<
0
)
goto
done
;
}
sk
->
sk_max_ack_backlog
=
backlog
;
sk
->
sk_ack_backlog
=
0
;
sk
->
sk_state
=
BT_LISTEN
;
...
...
@@ -852,8 +808,7 @@ void l2cap_sock_kill(struct sock *sk)
/* Kill poor orphan */
l2cap_chan_free
(
l2cap_pi
(
sk
)
->
chan
);
bt_sock_unlink
(
&
l2cap_sk_list
,
sk
);
l2cap_chan_destroy
(
l2cap_pi
(
sk
)
->
chan
);
sock_set_flag
(
sk
,
SOCK_DEAD
);
sock_put
(
sk
);
}
...
...
@@ -1069,7 +1024,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g
setup_timer
(
&
sk
->
sk_timer
,
l2cap_sock_timeout
,
(
unsigned
long
)
sk
);
bt_sock_link
(
&
l2cap_sk_list
,
sk
);
return
sk
;
}
...
...
@@ -1096,7 +1050,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
if
(
!
sk
)
return
-
ENOMEM
;
chan
=
l2cap_chan_
alloc
(
sk
);
chan
=
l2cap_chan_
create
(
sk
);
if
(
!
chan
)
{
l2cap_sock_kill
(
sk
);
return
-
ENOMEM
;
...
...
net/bluetooth/mgmt.c
浏览文件 @
15cb3096
...
...
@@ -1033,6 +1033,9 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
}
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
ACL_LINK
,
&
cp
->
bdaddr
);
if
(
!
conn
)
conn
=
hci_conn_hash_lookup_ba
(
hdev
,
LE_LINK
,
&
cp
->
bdaddr
);
if
(
!
conn
)
{
err
=
cmd_status
(
sk
,
index
,
MGMT_OP_DISCONNECT
,
ENOTCONN
);
goto
failed
;
...
...
net/bluetooth/rfcomm/core.c
浏览文件 @
15cb3096
...
...
@@ -2096,7 +2096,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if
(
!
test_and_clear_bit
(
RFCOMM_AUTH_PENDING
,
&
d
->
flags
))
continue
;
if
(
!
status
)
if
(
!
status
&&
hci_conn_check_secure
(
conn
,
d
->
sec_level
)
)
set_bit
(
RFCOMM_AUTH_ACCEPT
,
&
d
->
flags
);
else
set_bit
(
RFCOMM_AUTH_REJECT
,
&
d
->
flags
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录