Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
5f779bbd
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
5f779bbd
编写于
12月 06, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next
上级
d7a4858c
5a13b095
变更
18
展开全部
隐藏空白更改
内联
并排
Showing
18 changed file
with
880 addition
and
281 deletion
+880
-281
drivers/bluetooth/Kconfig
drivers/bluetooth/Kconfig
+3
-3
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmrvl_sdio.c
+13
-2
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+1
-2
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+8
-0
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+5
-0
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+38
-0
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+20
-8
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+1
-1
include/net/bluetooth/mgmt.h
include/net/bluetooth/mgmt.h
+45
-4
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+3
-5
net/bluetooth/cmtp/core.c
net/bluetooth/cmtp/core.c
+3
-2
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+1
-1
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+12
-19
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+126
-26
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_core.c
+66
-35
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_sock.c
+13
-3
net/bluetooth/mgmt.c
net/bluetooth/mgmt.c
+497
-163
net/bluetooth/smp.c
net/bluetooth/smp.c
+25
-7
未找到文件。
drivers/bluetooth/Kconfig
浏览文件 @
5f779bbd
...
...
@@ -188,7 +188,7 @@ config BT_MRVL
The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support
Marvell Bluetooth devices, such as 8688/8787.
Marvell Bluetooth devices, such as 8688/8787
/8797
.
Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module.
...
...
@@ -201,8 +201,8 @@ config BT_MRVL_SDIO
The driver for Marvell Bluetooth chipsets with SDIO interface.
This driver is required if you want to use Marvell Bluetooth
devices with SDIO interface. Currently SD8688/SD8787
chipsets are
supported.
devices with SDIO interface. Currently SD8688/SD8787
/SD8797
chipsets are
supported.
Say Y here to compile support for Marvell BT-over-SDIO driver
into the kernel or say M to compile it as module.
...
...
drivers/bluetooth/btmrvl_sdio.c
浏览文件 @
5f779bbd
...
...
@@ -65,7 +65,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
.
io_port_1
=
0x01
,
.
io_port_2
=
0x02
,
};
static
const
struct
btmrvl_sdio_card_reg
btmrvl_reg_87
87
=
{
static
const
struct
btmrvl_sdio_card_reg
btmrvl_reg_87
xx
=
{
.
cfg
=
0x00
,
.
host_int_mask
=
0x02
,
.
host_intstatus
=
0x03
,
...
...
@@ -92,7 +92,14 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static
const
struct
btmrvl_sdio_device
btmrvl_sdio_sd8787
=
{
.
helper
=
NULL
,
.
firmware
=
"mrvl/sd8787_uapsta.bin"
,
.
reg
=
&
btmrvl_reg_8787
,
.
reg
=
&
btmrvl_reg_87xx
,
.
sd_blksz_fw_dl
=
256
,
};
static
const
struct
btmrvl_sdio_device
btmrvl_sdio_sd8797
=
{
.
helper
=
NULL
,
.
firmware
=
"mrvl/sd8797_uapsta.bin"
,
.
reg
=
&
btmrvl_reg_87xx
,
.
sd_blksz_fw_dl
=
256
,
};
...
...
@@ -103,6 +110,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8787 Bluetooth device */
{
SDIO_DEVICE
(
SDIO_VENDOR_ID_MARVELL
,
0x911A
),
.
driver_data
=
(
unsigned
long
)
&
btmrvl_sdio_sd8787
},
/* Marvell SD8797 Bluetooth device */
{
SDIO_DEVICE
(
SDIO_VENDOR_ID_MARVELL
,
0x912A
),
.
driver_data
=
(
unsigned
long
)
&
btmrvl_sdio_sd8797
},
{
}
/* Terminating entry */
};
...
...
@@ -1076,3 +1086,4 @@ MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE
(
"sd8688_helper.bin"
);
MODULE_FIRMWARE
(
"sd8688.bin"
);
MODULE_FIRMWARE
(
"mrvl/sd8787_uapsta.bin"
);
MODULE_FIRMWARE
(
"mrvl/sd8797_uapsta.bin"
);
drivers/bluetooth/btusb.c
浏览文件 @
5f779bbd
...
...
@@ -785,9 +785,8 @@ static int btusb_send_frame(struct sk_buff *skb)
usb_mark_last_busy
(
data
->
udev
);
}
usb_free_urb
(
urb
);
done:
usb_free_urb
(
urb
);
return
err
;
}
...
...
drivers/bluetooth/hci_vhci.c
浏览文件 @
5f779bbd
...
...
@@ -41,6 +41,8 @@
#define VERSION "1.3"
static
bool
amp
;
struct
vhci_data
{
struct
hci_dev
*
hdev
;
...
...
@@ -239,6 +241,9 @@ static int vhci_open(struct inode *inode, struct file *file)
hdev
->
bus
=
HCI_VIRTUAL
;
hdev
->
driver_data
=
data
;
if
(
amp
)
hdev
->
dev_type
=
HCI_AMP
;
hdev
->
open
=
vhci_open_dev
;
hdev
->
close
=
vhci_close_dev
;
hdev
->
flush
=
vhci_flush
;
...
...
@@ -303,6 +308,9 @@ static void __exit vhci_exit(void)
module_init
(
vhci_init
);
module_exit
(
vhci_exit
);
module_param
(
amp
,
bool
,
0644
);
MODULE_PARM_DESC
(
amp
,
"Create AMP controller device"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth virtual HCI driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
include/net/bluetooth/bluetooth.h
浏览文件 @
5f779bbd
...
...
@@ -36,6 +36,11 @@
#define PF_BLUETOOTH AF_BLUETOOTH
#endif
/* Bluetooth versions */
#define BLUETOOTH_VER_1_1 1
#define BLUETOOTH_VER_1_2 2
#define BLUETOOTH_VER_2_0 3
/* Reserv for core and drivers use */
#define BT_SKB_RESERVE 8
...
...
include/net/bluetooth/hci.h
浏览文件 @
5f779bbd
...
...
@@ -88,6 +88,14 @@ enum {
HCI_RESET
,
};
/*
* BR/EDR and/or LE controller flags: the flags defined here should represent
* states from the controller.
*/
enum
{
HCI_LE_SCAN
,
};
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
...
...
@@ -453,6 +461,14 @@ struct hci_rp_user_confirm_reply {
#define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d
#define HCI_OP_USER_PASSKEY_REPLY 0x042e
struct
hci_cp_user_passkey_reply
{
bdaddr_t
bdaddr
;
__le32
passkey
;
}
__packed
;
#define HCI_OP_USER_PASSKEY_NEG_REPLY 0x042f
#define HCI_OP_REMOTE_OOB_DATA_REPLY 0x0430
struct
hci_cp_remote_oob_data_reply
{
bdaddr_t
bdaddr
;
...
...
@@ -669,6 +685,12 @@ struct hci_rp_read_local_oob_data {
#define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58
#define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66
struct
hci_rp_read_flow_control_mode
{
__u8
status
;
__u8
mode
;
}
__packed
;
#define HCI_OP_WRITE_LE_HOST_SUPPORTED 0x0c6d
struct
hci_cp_write_le_host_supported
{
__u8
le
;
...
...
@@ -760,6 +782,15 @@ struct hci_rp_le_read_buffer_size {
__u8
le_max_pkt
;
}
__packed
;
#define HCI_OP_LE_SET_SCAN_PARAM 0x200b
struct
hci_cp_le_set_scan_param
{
__u8
type
;
__le16
interval
;
__le16
window
;
__u8
own_address_type
;
__u8
filter_policy
;
}
__packed
;
#define HCI_OP_LE_SET_SCAN_ENABLE 0x200c
struct
hci_cp_le_set_scan_enable
{
__u8
enable
;
...
...
@@ -1076,6 +1107,11 @@ struct hci_ev_user_confirm_req {
__le32
passkey
;
}
__packed
;
#define HCI_EV_USER_PASSKEY_REQUEST 0x34
struct
hci_ev_user_passkey_req
{
bdaddr_t
bdaddr
;
}
__packed
;
#define HCI_EV_REMOTE_OOB_DATA_REQUEST 0x35
struct
hci_ev_remote_oob_data_request
{
bdaddr_t
bdaddr
;
...
...
@@ -1331,4 +1367,6 @@ struct hci_inquiry_req {
};
#define IREQ_CACHE_FLUSH 0x0001
extern
int
enable_hs
;
#endif
/* __HCI_H */
include/net/bluetooth/hci_core.h
浏览文件 @
5f779bbd
...
...
@@ -170,6 +170,8 @@ struct hci_dev {
__u32
amp_max_flush_to
;
__u32
amp_be_flush_to
;
__u8
flow_ctl_mode
;
unsigned
int
auto_accept_delay
;
unsigned
long
quirks
;
...
...
@@ -250,6 +252,8 @@ struct hci_dev {
struct
module
*
owner
;
unsigned
long
dev_flags
;
int
(
*
open
)(
struct
hci_dev
*
hdev
);
int
(
*
close
)(
struct
hci_dev
*
hdev
);
int
(
*
flush
)(
struct
hci_dev
*
hdev
);
...
...
@@ -917,11 +921,13 @@ int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
int
mgmt_write_scan_failed
(
struct
hci_dev
*
hdev
,
u8
scan
,
u8
status
);
int
mgmt_new_link_key
(
struct
hci_dev
*
hdev
,
struct
link_key
*
key
,
u8
persistent
);
int
mgmt_connected
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
type
);
int
mgmt_disconnected
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
type
);
int
mgmt_disconnect_failed
(
struct
hci_dev
*
hdev
);
int
mgmt_connect_failed
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
type
,
u8
status
);
int
mgmt_connected
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
link_type
,
u8
addr_type
);
int
mgmt_disconnected
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
link_type
,
u8
addr_type
);
int
mgmt_disconnect_failed
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_connect_failed
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
link_type
,
u8
addr_type
,
u8
status
);
int
mgmt_pin_code_request
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
secure
);
int
mgmt_pin_code_reply_complete
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
...
...
@@ -933,14 +939,20 @@ int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8
status
);
int
mgmt_user_confirm_neg_reply_complete
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_user_passkey_request
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
int
mgmt_user_passkey_reply_complete
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_user_passkey_neg_reply_complete
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_auth_failed
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_set_local_name_complete
(
struct
hci_dev
*
hdev
,
u8
*
name
,
u8
status
);
int
mgmt_read_local_oob_data_reply_complete
(
struct
hci_dev
*
hdev
,
u8
*
hash
,
u8
*
randomizer
,
u8
status
);
int
mgmt_device_found
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
type
,
u8
*
dev_class
,
s8
rssi
,
u8
*
eir
);
int
mgmt_device_found
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
link_
type
,
u8
addr_type
,
u8
*
dev_class
,
s8
rssi
,
u8
*
eir
);
int
mgmt_remote_name
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
*
name
);
int
mgmt_inquiry_failed
(
struct
hci_dev
*
hdev
,
u8
status
);
int
mgmt_start_discovery_failed
(
struct
hci_dev
*
hdev
,
u8
status
);
int
mgmt_stop_discovery_failed
(
struct
hci_dev
*
hdev
,
u8
status
);
int
mgmt_discovering
(
struct
hci_dev
*
hdev
,
u8
discovering
);
int
mgmt_device_blocked
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
int
mgmt_device_unblocked
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
...
...
include/net/bluetooth/l2cap.h
浏览文件 @
5f779bbd
...
...
@@ -792,7 +792,6 @@ static inline __u8 __ctrl_size(struct l2cap_chan *chan)
}
extern
int
disable_ertm
;
extern
int
enable_hs
;
int
l2cap_init_sockets
(
void
);
void
l2cap_cleanup_sockets
(
void
);
...
...
@@ -810,5 +809,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan);
int
l2cap_chan_send
(
struct
l2cap_chan
*
chan
,
struct
msghdr
*
msg
,
size_t
len
,
u32
priority
);
void
l2cap_chan_busy
(
struct
l2cap_chan
*
chan
,
int
busy
);
int
l2cap_chan_check_security
(
struct
l2cap_chan
*
chan
);
#endif
/* __L2CAP_H */
include/net/bluetooth/mgmt.h
浏览文件 @
5f779bbd
...
...
@@ -23,6 +23,23 @@
#define MGMT_INDEX_NONE 0xFFFF
#define MGMT_STATUS_SUCCESS 0x00
#define MGMT_STATUS_UNKNOWN_COMMAND 0x01
#define MGMT_STATUS_NOT_CONNECTED 0x02
#define MGMT_STATUS_FAILED 0x03
#define MGMT_STATUS_CONNECT_FAILED 0x04
#define MGMT_STATUS_AUTH_FAILED 0x05
#define MGMT_STATUS_NOT_PAIRED 0x06
#define MGMT_STATUS_NO_RESOURCES 0x07
#define MGMT_STATUS_TIMEOUT 0x08
#define MGMT_STATUS_ALREADY_CONNECTED 0x09
#define MGMT_STATUS_BUSY 0x0a
#define MGMT_STATUS_REJECTED 0x0b
#define MGMT_STATUS_NOT_SUPPORTED 0x0c
#define MGMT_STATUS_INVALID_PARAMS 0x0d
#define MGMT_STATUS_DISCONNECTED 0x0e
#define MGMT_STATUS_NOT_POWERED 0x0f
struct
mgmt_hdr
{
__le16
opcode
;
__le16
index
;
...
...
@@ -119,6 +136,10 @@ struct mgmt_cp_remove_keys {
bdaddr_t
bdaddr
;
__u8
disconnect
;
}
__packed
;
struct
mgmt_rp_remove_keys
{
bdaddr_t
bdaddr
;
__u8
status
;
};
#define MGMT_OP_DISCONNECT 0x000F
struct
mgmt_cp_disconnect
{
...
...
@@ -126,11 +147,12 @@ struct mgmt_cp_disconnect {
}
__packed
;
struct
mgmt_rp_disconnect
{
bdaddr_t
bdaddr
;
__u8
status
;
}
__packed
;
#define MGMT_ADDR_BREDR 0x00
#define MGMT_ADDR_LE
0x01
#define MGMT_ADDR_
BREDR_LE
0x02
#define MGMT_ADDR_LE
_PUBLIC
0x01
#define MGMT_ADDR_
LE_RANDOM
0x02
#define MGMT_ADDR_INVALID 0xff
struct
mgmt_addr_info
{
...
...
@@ -167,11 +189,11 @@ struct mgmt_cp_set_io_capability {
#define MGMT_OP_PAIR_DEVICE 0x0014
struct
mgmt_cp_pair_device
{
bdaddr_t
bd
addr
;
struct
mgmt_addr_info
addr
;
__u8
io_cap
;
}
__packed
;
struct
mgmt_rp_pair_device
{
bdaddr_t
bd
addr
;
struct
mgmt_addr_info
addr
;
__u8
status
;
}
__packed
;
...
...
@@ -210,6 +232,9 @@ struct mgmt_cp_remove_remote_oob_data {
}
__packed
;
#define MGMT_OP_START_DISCOVERY 0x001B
struct
mgmt_cp_start_discovery
{
__u8
type
;
}
__packed
;
#define MGMT_OP_STOP_DISCOVERY 0x001C
...
...
@@ -228,6 +253,17 @@ struct mgmt_cp_set_fast_connectable {
__u8
enable
;
}
__packed
;
#define MGMT_OP_USER_PASSKEY_REPLY 0x0020
struct
mgmt_cp_user_passkey_reply
{
bdaddr_t
bdaddr
;
__le32
passkey
;
}
__packed
;
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x0021
struct
mgmt_cp_user_passkey_neg_reply
{
bdaddr_t
bdaddr
;
}
__packed
;
#define MGMT_EV_CMD_COMPLETE 0x0001
struct
mgmt_ev_cmd_complete
{
__le16
opcode
;
...
...
@@ -322,3 +358,8 @@ struct mgmt_ev_device_blocked {
struct
mgmt_ev_device_unblocked
{
bdaddr_t
bdaddr
;
}
__packed
;
#define MGMT_EV_USER_PASSKEY_REQUEST 0x0017
struct
mgmt_ev_user_passkey_request
{
bdaddr_t
bdaddr
;
}
__packed
;
net/bluetooth/bnep/core.c
浏览文件 @
5f779bbd
...
...
@@ -77,17 +77,12 @@ static struct bnep_session *__bnep_get_session(u8 *dst)
static
void
__bnep_link_session
(
struct
bnep_session
*
s
)
{
/* It's safe to call __module_get() here because sessions are added
by the socket layer which has to hold the reference to this module.
*/
__module_get
(
THIS_MODULE
);
list_add
(
&
s
->
list
,
&
bnep_session_list
);
}
static
void
__bnep_unlink_session
(
struct
bnep_session
*
s
)
{
list_del
(
&
s
->
list
);
module_put
(
THIS_MODULE
);
}
static
int
bnep_send
(
struct
bnep_session
*
s
,
void
*
data
,
size_t
len
)
...
...
@@ -528,6 +523,7 @@ static int bnep_session(void *arg)
up_write
(
&
bnep_session_sem
);
free_netdev
(
dev
);
module_put_and_exit
(
0
);
return
0
;
}
...
...
@@ -614,9 +610,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
__bnep_link_session
(
s
);
__module_get
(
THIS_MODULE
);
s
->
task
=
kthread_run
(
bnep_session
,
s
,
"kbnepd %s"
,
dev
->
name
);
if
(
IS_ERR
(
s
->
task
))
{
/* Session thread start failed, gotta cleanup. */
module_put
(
THIS_MODULE
);
unregister_netdev
(
dev
);
__bnep_unlink_session
(
s
);
err
=
PTR_ERR
(
s
->
task
);
...
...
net/bluetooth/cmtp/core.c
浏览文件 @
5f779bbd
...
...
@@ -65,14 +65,12 @@ static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
static
void
__cmtp_link_session
(
struct
cmtp_session
*
session
)
{
__module_get
(
THIS_MODULE
);
list_add
(
&
session
->
list
,
&
cmtp_session_list
);
}
static
void
__cmtp_unlink_session
(
struct
cmtp_session
*
session
)
{
list_del
(
&
session
->
list
);
module_put
(
THIS_MODULE
);
}
static
void
__cmtp_copy_session
(
struct
cmtp_session
*
session
,
struct
cmtp_conninfo
*
ci
)
...
...
@@ -325,6 +323,7 @@ static int cmtp_session(void *arg)
up_write
(
&
cmtp_session_sem
);
kfree
(
session
);
module_put_and_exit
(
0
);
return
0
;
}
...
...
@@ -374,9 +373,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
__cmtp_link_session
(
session
);
__module_get
(
THIS_MODULE
);
session
->
task
=
kthread_run
(
cmtp_session
,
session
,
"kcmtpd_ctr_%d"
,
session
->
num
);
if
(
IS_ERR
(
session
->
task
))
{
module_put
(
THIS_MODULE
);
err
=
PTR_ERR
(
session
->
task
);
goto
unlink
;
}
...
...
net/bluetooth/hci_conn.c
浏览文件 @
5f779bbd
...
...
@@ -123,7 +123,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn)
BT_DBG
(
"%p"
,
conn
);
if
(
conn
->
hdev
->
hci_ver
<
2
)
if
(
conn
->
hdev
->
hci_ver
<
BLUETOOTH_VER_1_
2
)
return
;
bacpy
(
&
cp
.
bdaddr
,
&
conn
->
dst
);
...
...
net/bluetooth/hci_core.c
浏览文件 @
5f779bbd
...
...
@@ -54,6 +54,8 @@
#define AUTO_OFF_TIMEOUT 2000
int
enable_hs
;
static
void
hci_cmd_task
(
unsigned
long
arg
);
static
void
hci_rx_task
(
unsigned
long
arg
);
static
void
hci_tx_task
(
unsigned
long
arg
);
...
...
@@ -228,18 +230,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
hci_send_cmd
(
hdev
,
HCI_OP_READ_BUFFER_SIZE
,
0
,
NULL
);
#if 0
/* Host buffer size */
{
struct hci_cp_host_buffer_size cp;
cp.acl_mtu = cpu_to_le16(HCI_MAX_ACL_SIZE);
cp.sco_mtu = HCI_MAX_SCO_SIZE;
cp.acl_max_pkt = cpu_to_le16(0xffff);
cp.sco_max_pkt = cpu_to_le16(0xffff);
hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
}
#endif
/* Read BD Address */
hci_send_cmd
(
hdev
,
HCI_OP_READ_BD_ADDR
,
0
,
NULL
);
...
...
@@ -521,8 +511,9 @@ int hci_dev_open(__u16 dev)
if
(
test_bit
(
HCI_QUIRK_RAW_DEVICE
,
&
hdev
->
quirks
))
set_bit
(
HCI_RAW
,
&
hdev
->
flags
);
/* Treat all non BR/EDR controllers as raw devices for now */
if
(
hdev
->
dev_type
!=
HCI_BREDR
)
/* Treat all non BR/EDR controllers as raw devices if
enable_hs is not set */
if
(
hdev
->
dev_type
!=
HCI_BREDR
&&
!
enable_hs
)
set_bit
(
HCI_RAW
,
&
hdev
->
flags
);
if
(
hdev
->
open
(
hdev
))
{
...
...
@@ -1336,14 +1327,12 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct
bdaddr_list
*
entry
;
if
(
bacmp
(
bdaddr
,
BDADDR_ANY
)
==
0
)
{
if
(
bacmp
(
bdaddr
,
BDADDR_ANY
)
==
0
)
return
hci_blacklist_clear
(
hdev
);
}
entry
=
hci_blacklist_lookup
(
hdev
,
bdaddr
);
if
(
!
entry
)
{
if
(
!
entry
)
return
-
ENOENT
;
}
list_del
(
&
entry
->
list
);
kfree
(
entry
);
...
...
@@ -1451,12 +1440,13 @@ int hci_register_dev(struct hci_dev *hdev)
sprintf
(
hdev
->
name
,
"hci%d"
,
id
);
hdev
->
id
=
id
;
list_add
(
&
hdev
->
list
,
head
);
list_add
_tail
(
&
hdev
->
list
,
head
);
atomic_set
(
&
hdev
->
refcnt
,
1
);
spin_lock_init
(
&
hdev
->
lock
);
hdev
->
flags
=
0
;
hdev
->
dev_flags
=
0
;
hdev
->
pkt_type
=
(
HCI_DM1
|
HCI_DH1
|
HCI_HV1
);
hdev
->
esco_type
=
(
ESCO_HV1
);
hdev
->
link_mode
=
(
HCI_LM_ACCEPT
);
...
...
@@ -2614,3 +2604,6 @@ int hci_cancel_inquiry(struct hci_dev *hdev)
return
hci_send_cmd
(
hdev
,
HCI_OP_INQUIRY_CANCEL
,
0
,
NULL
);
}
module_param
(
enable_hs
,
bool
,
0644
);
MODULE_PARM_DESC
(
enable_hs
,
"Enable High Speed"
);
net/bluetooth/hci_event.c
浏览文件 @
5f779bbd
...
...
@@ -55,8 +55,12 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
if
(
status
)
if
(
status
)
{
hci_dev_lock
(
hdev
);
mgmt_stop_discovery_failed
(
hdev
,
status
);
hci_dev_unlock
(
hdev
);
return
;
}
clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
...
...
@@ -190,6 +194,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit
(
HCI_RESET
,
&
hdev
->
flags
);
hci_req_complete
(
hdev
,
HCI_OP_RESET
,
status
);
hdev
->
dev_flags
=
0
;
}
static
void
hci_cc_write_local_name
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
...
...
@@ -494,7 +500,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
/* CSR 1.1 dongles does not accept any bitfield so don't try to set
* any event mask for pre 1.2 devices */
if
(
hdev
->
lmp_ver
<=
1
)
if
(
hdev
->
hci_ver
<
BLUETOOTH_VER_1_2
)
return
;
events
[
4
]
|=
0x01
;
/* Flow Specification Complete */
...
...
@@ -558,7 +564,7 @@ static void hci_setup(struct hci_dev *hdev)
{
hci_setup_event_mask
(
hdev
);
if
(
hdev
->
lmp_ver
>
1
)
if
(
hdev
->
hci_ver
>
BLUETOOTH_VER_1_
1
)
hci_send_cmd
(
hdev
,
HCI_OP_READ_LOCAL_COMMANDS
,
0
,
NULL
);
if
(
hdev
->
features
[
6
]
&
LMP_SIMPLE_PAIR
)
{
...
...
@@ -713,6 +719,21 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
hci_req_complete
(
hdev
,
HCI_OP_READ_LOCAL_EXT_FEATURES
,
rp
->
status
);
}
static
void
hci_cc_read_flow_control_mode
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_read_flow_control_mode
*
rp
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
rp
->
status
);
if
(
rp
->
status
)
return
;
hdev
->
flow_ctl_mode
=
rp
->
mode
;
hci_req_complete
(
hdev
,
HCI_OP_READ_FLOW_CONTROL_MODE
,
rp
->
status
);
}
static
void
hci_cc_read_buffer_size
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_read_buffer_size
*
rp
=
(
void
*
)
skb
->
data
;
...
...
@@ -927,6 +948,37 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
hci_dev_unlock
(
hdev
);
}
static
void
hci_cc_user_passkey_reply
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_user_confirm_reply
*
rp
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
rp
->
status
);
hci_dev_lock
(
hdev
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_user_passkey_reply_complete
(
hdev
,
&
rp
->
bdaddr
,
rp
->
status
);
hci_dev_unlock
(
hdev
);
}
static
void
hci_cc_user_passkey_neg_reply
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_user_confirm_reply
*
rp
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
rp
->
status
);
hci_dev_lock
(
hdev
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_user_passkey_neg_reply_complete
(
hdev
,
&
rp
->
bdaddr
,
rp
->
status
);
hci_dev_unlock
(
hdev
);
}
static
void
hci_cc_read_local_oob_data_reply
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
...
...
@@ -940,6 +992,13 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
hci_dev_unlock
(
hdev
);
}
static
void
hci_cc_le_set_scan_param
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
__u8
status
=
*
((
__u8
*
)
skb
->
data
);
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
}
static
void
hci_cc_le_set_scan_enable
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
...
...
@@ -956,12 +1015,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
return
;
if
(
cp
->
enable
==
0x01
)
{
set_bit
(
HCI_LE_SCAN
,
&
hdev
->
dev_flags
);
del_timer
(
&
hdev
->
adv_timer
);
hci_dev_lock
(
hdev
);
hci_adv_entries_clear
(
hdev
);
hci_dev_unlock
(
hdev
);
}
else
if
(
cp
->
enable
==
0x00
)
{
clear_bit
(
HCI_LE_SCAN
,
&
hdev
->
dev_flags
);
mod_timer
(
&
hdev
->
adv_timer
,
jiffies
+
ADV_CLEAR_TIMEOUT
);
}
}
...
...
@@ -1014,7 +1077,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
hci_conn_check_pending
(
hdev
);
hci_dev_lock
(
hdev
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_
inqui
ry_failed
(
hdev
,
status
);
mgmt_
start_discove
ry_failed
(
hdev
,
status
);
hci_dev_unlock
(
hdev
);
return
;
}
...
...
@@ -1437,7 +1500,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data
.
rssi
=
0x00
;
data
.
ssp_mode
=
0x00
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
0x00
,
info
->
dev_class
,
0
,
NULL
);
}
...
...
@@ -1472,7 +1535,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn
->
state
=
BT_CONFIG
;
hci_conn_hold
(
conn
);
conn
->
disc_timeout
=
HCI_DISCONN_TIMEOUT
;
mgmt_connected
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
);
mgmt_connected
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
,
conn
->
dst_type
);
}
else
conn
->
state
=
BT_CONNECTED
;
...
...
@@ -1494,7 +1558,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
}
/* Set packet type for incoming connection */
if
(
!
conn
->
out
&&
hdev
->
hci_ver
<
3
)
{
if
(
!
conn
->
out
&&
hdev
->
hci_ver
<
BLUETOOTH_VER_2_0
)
{
struct
hci_cp_change_conn_ptype
cp
;
cp
.
handle
=
ev
->
handle
;
cp
.
pkt_type
=
cpu_to_le16
(
conn
->
pkt_type
);
...
...
@@ -1505,7 +1569,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
conn
->
state
=
BT_CLOSED
;
if
(
conn
->
type
==
ACL_LINK
)
mgmt_connect_failed
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
,
ev
->
status
);
conn
->
dst_type
,
ev
->
status
);
}
if
(
conn
->
type
==
ACL_LINK
)
...
...
@@ -1604,26 +1668,27 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
BT_DBG
(
"%s status %d"
,
hdev
->
name
,
ev
->
status
);
if
(
ev
->
status
)
{
hci_dev_lock
(
hdev
);
mgmt_disconnect_failed
(
hdev
);
hci_dev_unlock
(
hdev
);
return
;
}
hci_dev_lock
(
hdev
);
conn
=
hci_conn_hash_lookup_handle
(
hdev
,
__le16_to_cpu
(
ev
->
handle
));
if
(
!
conn
)
goto
unlock
;
conn
->
state
=
BT_CLOSED
;
if
(
ev
->
status
==
0
)
conn
->
state
=
BT_CLOSED
;
if
(
conn
->
type
==
ACL_LINK
||
conn
->
type
==
LE_LINK
)
mgmt_disconnected
(
hdev
,
&
conn
->
dst
,
conn
->
type
);
if
(
conn
->
type
==
ACL_LINK
||
conn
->
type
==
LE_LINK
)
{
if
(
ev
->
status
!=
0
)
mgmt_disconnect_failed
(
hdev
,
&
conn
->
dst
,
ev
->
status
);
else
mgmt_disconnected
(
hdev
,
&
conn
->
dst
,
conn
->
type
,
conn
->
dst_type
);
}
hci_proto_disconn_cfm
(
conn
,
ev
->
reason
);
hci_conn_del
(
conn
);
if
(
ev
->
status
==
0
)
{
hci_proto_disconn_cfm
(
conn
,
ev
->
reason
);
hci_conn_del
(
conn
);
}
unlock:
hci_dev_unlock
(
hdev
);
...
...
@@ -1961,6 +2026,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_write_ca_timeout
(
hdev
,
skb
);
break
;
case
HCI_OP_READ_FLOW_CONTROL_MODE
:
hci_cc_read_flow_control_mode
(
hdev
,
skb
);
break
;
case
HCI_OP_READ_LOCAL_AMP_INFO
:
hci_cc_read_local_amp_info
(
hdev
,
skb
);
break
;
...
...
@@ -2009,6 +2078,17 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_user_confirm_neg_reply
(
hdev
,
skb
);
break
;
case
HCI_OP_USER_PASSKEY_REPLY
:
hci_cc_user_passkey_reply
(
hdev
,
skb
);
break
;
case
HCI_OP_USER_PASSKEY_NEG_REPLY
:
hci_cc_user_passkey_neg_reply
(
hdev
,
skb
);
case
HCI_OP_LE_SET_SCAN_PARAM
:
hci_cc_le_set_scan_param
(
hdev
,
skb
);
break
;
case
HCI_OP_LE_SET_SCAN_ENABLE
:
hci_cc_le_set_scan_enable
(
hdev
,
skb
);
break
;
...
...
@@ -2096,7 +2176,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
case
HCI_OP_DISCONNECT
:
if
(
ev
->
status
!=
0
)
mgmt_disconnect_failed
(
hdev
);
mgmt_disconnect_failed
(
hdev
,
NULL
,
ev
->
status
);
break
;
case
HCI_OP_LE_CREATE_CONN
:
...
...
@@ -2444,7 +2524,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x00
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
0x00
,
info
->
dev_class
,
info
->
rssi
,
NULL
);
}
...
...
@@ -2461,7 +2541,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x00
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
0x00
,
info
->
dev_class
,
info
->
rssi
,
NULL
);
}
...
...
@@ -2604,7 +2684,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x01
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
mgmt_device_found
(
hdev
,
&
info
->
bdaddr
,
ACL_LINK
,
0x00
,
info
->
dev_class
,
info
->
rssi
,
info
->
data
);
}
...
...
@@ -2768,6 +2848,21 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_user_passkey_request_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_user_passkey_req
*
ev
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s"
,
hdev
->
name
);
hci_dev_lock
(
hdev
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_user_passkey_request
(
hdev
,
&
ev
->
bdaddr
);
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_simple_pair_complete_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_simple_pair_complete
*
ev
=
(
void
*
)
skb
->
data
;
...
...
@@ -2868,14 +2963,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
}
if
(
ev
->
status
)
{
mgmt_connect_failed
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
,
ev
->
status
);
mgmt_connect_failed
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
,
conn
->
dst_type
,
ev
->
status
);
hci_proto_connect_cfm
(
conn
,
ev
->
status
);
conn
->
state
=
BT_CLOSED
;
hci_conn_del
(
conn
);
goto
unlock
;
}
mgmt_connected
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
);
mgmt_connected
(
hdev
,
&
ev
->
bdaddr
,
conn
->
type
,
conn
->
dst_type
);
conn
->
sec_level
=
BT_SECURITY_LOW
;
conn
->
handle
=
__le16_to_cpu
(
ev
->
handle
);
...
...
@@ -3106,6 +3202,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_user_confirm_request_evt
(
hdev
,
skb
);
break
;
case
HCI_EV_USER_PASSKEY_REQUEST
:
hci_user_passkey_request_evt
(
hdev
,
skb
);
break
;
case
HCI_EV_SIMPLE_PAIR_COMPLETE
:
hci_simple_pair_complete_evt
(
hdev
,
skb
);
break
;
...
...
net/bluetooth/l2cap_core.c
浏览文件 @
5f779bbd
...
...
@@ -57,7 +57,6 @@
#include <net/bluetooth/smp.h>
int
disable_ertm
;
int
enable_hs
;
static
u32
l2cap_feat_mask
=
L2CAP_FEAT_FIXED_CHAN
;
static
u8
l2cap_fixed_chan
[
8
]
=
{
L2CAP_FC_L2CAP
,
};
...
...
@@ -97,7 +96,6 @@ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16
return
c
;
}
return
NULL
;
}
static
struct
l2cap_chan
*
__l2cap_get_chan_by_scid
(
struct
l2cap_conn
*
conn
,
u16
cid
)
...
...
@@ -154,12 +152,9 @@ static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
list_for_each_entry
(
c
,
&
chan_list
,
global_l
)
{
if
(
c
->
sport
==
psm
&&
!
bacmp
(
&
bt_sk
(
c
->
sk
)
->
src
,
src
))
goto
found
;
return
c
;
}
c
=
NULL
;
found:
return
c
;
return
NULL
;
}
int
l2cap_add_psm
(
struct
l2cap_chan
*
chan
,
bdaddr_t
*
src
,
__le16
psm
)
...
...
@@ -234,8 +229,37 @@ static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer)
chan_put
(
chan
);
}
static
char
*
state_to_string
(
int
state
)
{
switch
(
state
)
{
case
BT_CONNECTED
:
return
"BT_CONNECTED"
;
case
BT_OPEN
:
return
"BT_OPEN"
;
case
BT_BOUND
:
return
"BT_BOUND"
;
case
BT_LISTEN
:
return
"BT_LISTEN"
;
case
BT_CONNECT
:
return
"BT_CONNECT"
;
case
BT_CONNECT2
:
return
"BT_CONNECT2"
;
case
BT_CONFIG
:
return
"BT_CONFIG"
;
case
BT_DISCONN
:
return
"BT_DISCONN"
;
case
BT_CLOSED
:
return
"BT_CLOSED"
;
}
return
"invalid state"
;
}
static
void
l2cap_state_change
(
struct
l2cap_chan
*
chan
,
int
state
)
{
BT_DBG
(
"%p %s -> %s"
,
chan
,
state_to_string
(
chan
->
state
),
state_to_string
(
state
));
chan
->
state
=
state
;
chan
->
ops
->
state_change
(
chan
->
data
,
state
);
}
...
...
@@ -518,7 +542,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
}
/* Service level security */
static
inline
int
l2cap
_check_security
(
struct
l2cap_chan
*
chan
)
int
l2cap_chan
_check_security
(
struct
l2cap_chan
*
chan
)
{
struct
l2cap_conn
*
conn
=
chan
->
conn
;
__u8
auth_type
;
...
...
@@ -664,7 +688,7 @@ static void l2cap_do_start(struct l2cap_chan *chan)
if
(
!
(
conn
->
info_state
&
L2CAP_INFO_FEAT_MASK_REQ_DONE
))
return
;
if
(
l2cap_check_security
(
chan
)
&&
if
(
l2cap_ch
an_ch
eck_security
(
chan
)
&&
__l2cap_no_conn_pending
(
chan
))
{
struct
l2cap_conn_req
req
;
req
.
scid
=
cpu_to_le16
(
chan
->
scid
);
...
...
@@ -754,7 +778,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
if
(
chan
->
state
==
BT_CONNECT
)
{
struct
l2cap_conn_req
req
;
if
(
!
l2cap_check_security
(
chan
)
||
if
(
!
l2cap_ch
an_ch
eck_security
(
chan
)
||
!
__l2cap_no_conn_pending
(
chan
))
{
bh_unlock_sock
(
sk
);
continue
;
...
...
@@ -787,7 +811,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
rsp
.
scid
=
cpu_to_le16
(
chan
->
dcid
);
rsp
.
dcid
=
cpu_to_le16
(
chan
->
scid
);
if
(
l2cap_check_security
(
chan
))
{
if
(
l2cap_ch
an_ch
eck_security
(
chan
))
{
if
(
bt_sk
(
sk
)
->
defer_setup
)
{
struct
sock
*
parent
=
bt_sk
(
sk
)
->
parent
;
rsp
.
result
=
cpu_to_le16
(
L2CAP_CR_PEND
);
...
...
@@ -1181,7 +1205,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
if
(
hcon
->
state
==
BT_CONNECTED
)
{
if
(
chan
->
chan_type
!=
L2CAP_CHAN_CONN_ORIENTED
)
{
__clear_chan_timer
(
chan
);
if
(
l2cap_check_security
(
chan
))
if
(
l2cap_ch
an_ch
eck_security
(
chan
))
l2cap_state_change
(
chan
,
BT_CONNECTED
);
}
else
l2cap_do_start
(
chan
);
...
...
@@ -1318,14 +1342,12 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq)
if
(
!
skb
)
return
;
do
{
if
(
bt_cb
(
skb
)
->
tx_seq
==
tx_seq
)
break
;
while
(
bt_cb
(
skb
)
->
tx_seq
!=
tx_seq
)
{
if
(
skb_queue_is_last
(
&
chan
->
tx_q
,
skb
))
return
;
}
while
((
skb
=
skb_queue_next
(
&
chan
->
tx_q
,
skb
)));
skb
=
skb_queue_next
(
&
chan
->
tx_q
,
skb
);
}
if
(
chan
->
remote_max_tx
&&
bt_cb
(
skb
)
->
retries
==
chan
->
remote_max_tx
)
{
...
...
@@ -1906,7 +1928,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
{
struct
l2cap_conf_efs
efs
;
switch
(
chan
->
mode
)
{
switch
(
chan
->
mode
)
{
case
L2CAP_MODE_ERTM
:
efs
.
id
=
chan
->
local_id
;
efs
.
stype
=
chan
->
local_stype
;
...
...
@@ -2606,7 +2628,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
chan
->
ident
=
cmd
->
ident
;
if
(
conn
->
info_state
&
L2CAP_INFO_FEAT_MASK_REQ_DONE
)
{
if
(
l2cap_check_security
(
chan
))
{
if
(
l2cap_ch
an_ch
eck_security
(
chan
))
{
if
(
bt_sk
(
sk
)
->
defer_setup
)
{
l2cap_state_change
(
chan
,
BT_CONNECT2
);
result
=
L2CAP_CR_PEND
;
...
...
@@ -3019,7 +3041,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
/* don't delete l2cap channel if sk is owned by user */
if
(
sock_owned_by_user
(
sk
))
{
l2cap_state_change
(
chan
,
BT_DISCONN
);
l2cap_state_change
(
chan
,
BT_DISCONN
);
__clear_chan_timer
(
chan
);
__set_chan_timer
(
chan
,
L2CAP_DISC_TIMEOUT
);
bh_unlock_sock
(
sk
);
...
...
@@ -3562,14 +3584,10 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
bt_cb
(
skb
)
->
sar
=
sar
;
next_skb
=
skb_peek
(
&
chan
->
srej_q
);
if
(
!
next_skb
)
{
__skb_queue_tail
(
&
chan
->
srej_q
,
skb
);
return
0
;
}
tx_seq_offset
=
__seq_offset
(
chan
,
tx_seq
,
chan
->
buffer_seq
);
do
{
while
(
next_skb
)
{
if
(
bt_cb
(
next_skb
)
->
tx_seq
==
tx_seq
)
return
-
EINVAL
;
...
...
@@ -3582,9 +3600,10 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
}
if
(
skb_queue_is_last
(
&
chan
->
srej_q
,
next_skb
))
break
;
}
while
((
next_skb
=
skb_queue_next
(
&
chan
->
srej_q
,
next_skb
)));
next_skb
=
NULL
;
else
next_skb
=
skb_queue_next
(
&
chan
->
srej_q
,
next_skb
);
}
__skb_queue_tail
(
&
chan
->
srej_q
,
skb
);
...
...
@@ -3788,7 +3807,7 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq)
}
}
static
void
l2cap_send_srejframe
(
struct
l2cap_chan
*
chan
,
u16
tx_seq
)
static
int
l2cap_send_srejframe
(
struct
l2cap_chan
*
chan
,
u16
tx_seq
)
{
struct
srej_list
*
new
;
u32
control
;
...
...
@@ -3799,6 +3818,9 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
l2cap_send_sframe
(
chan
,
control
);
new
=
kzalloc
(
sizeof
(
struct
srej_list
),
GFP_ATOMIC
);
if
(
!
new
)
return
-
ENOMEM
;
new
->
tx_seq
=
chan
->
expected_tx_seq
;
chan
->
expected_tx_seq
=
__next_seq
(
chan
,
chan
->
expected_tx_seq
);
...
...
@@ -3807,6 +3829,8 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
}
chan
->
expected_tx_seq
=
__next_seq
(
chan
,
chan
->
expected_tx_seq
);
return
0
;
}
static
inline
int
l2cap_data_channel_iframe
(
struct
l2cap_chan
*
chan
,
u32
rx_control
,
struct
sk_buff
*
skb
)
...
...
@@ -3877,7 +3901,12 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
return
0
;
}
}
l2cap_send_srejframe
(
chan
,
tx_seq
);
err
=
l2cap_send_srejframe
(
chan
,
tx_seq
);
if
(
err
<
0
)
{
l2cap_send_disconn_req
(
chan
->
conn
,
chan
,
-
err
);
return
err
;
}
}
}
else
{
expected_tx_seq_offset
=
__seq_offset
(
chan
,
...
...
@@ -3899,7 +3928,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
set_bit
(
CONN_SEND_PBIT
,
&
chan
->
conn_state
);
l2cap_send_srejframe
(
chan
,
tx_seq
);
err
=
l2cap_send_srejframe
(
chan
,
tx_seq
);
if
(
err
<
0
)
{
l2cap_send_disconn_req
(
chan
->
conn
,
chan
,
-
err
);
return
err
;
}
__clear_ack_timer
(
chan
);
}
...
...
@@ -3928,11 +3961,12 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
l2cap_retransmit_frames
(
chan
);
}
__set_ack_timer
(
chan
);
chan
->
num_acked
=
(
chan
->
num_acked
+
1
)
%
num_to_ack
;
if
(
chan
->
num_acked
==
num_to_ack
-
1
)
l2cap_send_ack
(
chan
);
else
__set_ack_timer
(
chan
);
return
0
;
...
...
@@ -4768,6 +4802,3 @@ void l2cap_exit(void)
module_param
(
disable_ertm
,
bool
,
0644
);
MODULE_PARM_DESC
(
disable_ertm
,
"Disable enhanced retransmission mode"
);
module_param
(
enable_hs
,
bool
,
0644
);
MODULE_PARM_DESC
(
enable_hs
,
"Enable High Speed"
);
net/bluetooth/l2cap_sock.c
浏览文件 @
5f779bbd
...
...
@@ -626,8 +626,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
chan
->
sec_level
=
sec
.
level
;
if
(
!
chan
->
conn
)
break
;
conn
=
chan
->
conn
;
if
(
conn
&&
chan
->
scid
==
L2CAP_CID_LE_DATA
)
{
/*change security for LE channels */
if
(
chan
->
scid
==
L2CAP_CID_LE_DATA
)
{
if
(
!
conn
->
hcon
->
out
)
{
err
=
-
EINVAL
;
break
;
...
...
@@ -635,9 +640,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
if
(
smp_conn_security
(
conn
,
sec
.
level
))
break
;
err
=
0
;
sk
->
sk_state
=
BT_CONFIG
;
/* or for ACL link, under defer_setup time */
}
else
if
(
sk
->
sk_state
==
BT_CONNECT2
&&
bt_sk
(
sk
)
->
defer_setup
)
{
err
=
l2cap_chan_check_security
(
chan
);
}
else
{
err
=
-
EINVAL
;
}
break
;
...
...
net/bluetooth/mgmt.c
浏览文件 @
5f779bbd
此差异已折叠。
点击以展开。
net/bluetooth/smp.c
浏览文件 @
5f779bbd
...
...
@@ -232,6 +232,18 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
return
0
;
}
static
void
smp_failure
(
struct
l2cap_conn
*
conn
,
u8
reason
,
u8
send
)
{
if
(
send
)
smp_send_cmd
(
conn
,
SMP_CMD_PAIRING_FAIL
,
sizeof
(
reason
),
&
reason
);
clear_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
hcon
->
pend
);
mgmt_auth_failed
(
conn
->
hcon
->
hdev
,
conn
->
dst
,
reason
);
del_timer
(
&
conn
->
security_timer
);
smp_chan_destroy
(
conn
);
}
static
void
confirm_work
(
struct
work_struct
*
work
)
{
struct
smp_chan
*
smp
=
container_of
(
work
,
struct
smp_chan
,
confirm
);
...
...
@@ -270,8 +282,7 @@ static void confirm_work(struct work_struct *work)
return
;
error:
smp_send_cmd
(
conn
,
SMP_CMD_PAIRING_FAIL
,
sizeof
(
reason
),
&
reason
);
smp_chan_destroy
(
conn
);
smp_failure
(
conn
,
reason
,
1
);
}
static
void
random_work
(
struct
work_struct
*
work
)
...
...
@@ -354,8 +365,7 @@ static void random_work(struct work_struct *work)
return
;
error:
smp_send_cmd
(
conn
,
SMP_CMD_PAIRING_FAIL
,
sizeof
(
reason
),
&
reason
);
smp_chan_destroy
(
conn
);
smp_failure
(
conn
,
reason
,
1
);
}
static
struct
smp_chan
*
smp_chan_create
(
struct
l2cap_conn
*
conn
)
...
...
@@ -379,7 +389,15 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
void
smp_chan_destroy
(
struct
l2cap_conn
*
conn
)
{
kfree
(
conn
->
smp_chan
);
struct
smp_chan
*
smp
=
conn
->
smp_chan
;
clear_bit
(
HCI_CONN_LE_SMP_PEND
,
&
conn
->
hcon
->
pend
);
if
(
smp
->
tfm
)
crypto_free_blkcipher
(
smp
->
tfm
);
kfree
(
smp
);
conn
->
smp_chan
=
NULL
;
hci_conn_put
(
conn
->
hcon
);
}
...
...
@@ -647,6 +665,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
break
;
case
SMP_CMD_PAIRING_FAIL
:
smp_failure
(
conn
,
skb
->
data
[
0
],
0
);
reason
=
0
;
err
=
-
EPERM
;
break
;
...
...
@@ -692,8 +711,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
done:
if
(
reason
)
smp_send_cmd
(
conn
,
SMP_CMD_PAIRING_FAIL
,
sizeof
(
reason
),
&
reason
);
smp_failure
(
conn
,
reason
,
1
);
kfree_skb
(
skb
);
return
err
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录