Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
f3b3e36f
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
170
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f3b3e36f
编写于
4月 07, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
上级
b0006e69
db940cb0
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
981 addition
and
291 deletion
+981
-291
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+5
-1
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+39
-3
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+24
-1
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+0
-2
include/net/bluetooth/mgmt.h
include/net/bluetooth/mgmt.h
+47
-0
net/bluetooth/bnep/bnep.h
net/bluetooth/bnep/bnep.h
+74
-74
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+37
-34
net/bluetooth/bnep/sock.c
net/bluetooth/bnep/sock.c
+1
-1
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/capi.c
+3
-3
net/bluetooth/cmtp/cmtp.h
net/bluetooth/cmtp/cmtp.h
+2
-9
net/bluetooth/cmtp/core.c
net/bluetooth/cmtp/core.c
+15
-10
net/bluetooth/cmtp/sock.c
net/bluetooth/cmtp/sock.c
+1
-1
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+80
-9
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+84
-15
net/bluetooth/hci_sysfs.c
net/bluetooth/hci_sysfs.c
+20
-20
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+44
-46
net/bluetooth/hidp/hidp.h
net/bluetooth/hidp/hidp.h
+3
-3
net/bluetooth/hidp/sock.c
net/bluetooth/hidp/sock.c
+4
-3
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_core.c
+20
-11
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_sock.c
+3
-2
net/bluetooth/mgmt.c
net/bluetooth/mgmt.c
+475
-43
未找到文件。
drivers/bluetooth/btusb.c
浏览文件 @
f3b3e36f
...
...
@@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = {
/* Apple MacBookAir3,1, MacBookAir3,2 */
{
USB_DEVICE
(
0x05ac
,
0x821b
)
},
/* Apple MacBookPro8,2 */
{
USB_DEVICE
(
0x05ac
,
0x821a
)
},
/* AVM BlueFRITZ! USB v2.0 */
{
USB_DEVICE
(
0x057c
,
0x3800
)
},
...
...
@@ -690,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb)
break
;
case
HCI_ACLDATA_PKT
:
if
(
!
data
->
bulk_tx_ep
||
hdev
->
conn_hash
.
acl_num
<
1
)
if
(
!
data
->
bulk_tx_ep
||
(
hdev
->
conn_hash
.
acl_num
<
1
&&
hdev
->
conn_hash
.
le_num
<
1
))
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
...
...
include/net/bluetooth/hci.h
浏览文件 @
f3b3e36f
...
...
@@ -84,6 +84,8 @@ enum {
HCI_SERVICE_CACHE
,
HCI_LINK_KEYS
,
HCI_DEBUG_KEYS
,
HCI_RESET
,
};
/* HCI ioctl defines */
...
...
@@ -426,6 +428,18 @@ struct hci_rp_user_confirm_reply {
#define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d
#define HCI_OP_REMOTE_OOB_DATA_REPLY 0x0430
struct
hci_cp_remote_oob_data_reply
{
bdaddr_t
bdaddr
;
__u8
hash
[
16
];
__u8
randomizer
[
16
];
}
__packed
;
#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY 0x0433
struct
hci_cp_remote_oob_data_neg_reply
{
bdaddr_t
bdaddr
;
}
__packed
;
#define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434
struct
hci_cp_io_capability_neg_reply
{
bdaddr_t
bdaddr
;
...
...
@@ -535,15 +549,17 @@ struct hci_cp_delete_stored_link_key {
__u8
delete_all
;
}
__packed
;
#define HCI_MAX_NAME_LENGTH 248
#define HCI_OP_WRITE_LOCAL_NAME 0x0c13
struct
hci_cp_write_local_name
{
__u8
name
[
248
];
__u8
name
[
HCI_MAX_NAME_LENGTH
];
}
__packed
;
#define HCI_OP_READ_LOCAL_NAME 0x0c14
struct
hci_rp_read_local_name
{
__u8
status
;
__u8
name
[
248
];
__u8
name
[
HCI_MAX_NAME_LENGTH
];
}
__packed
;
#define HCI_OP_WRITE_CA_TIMEOUT 0x0c16
...
...
@@ -600,6 +616,14 @@ struct hci_cp_host_buffer_size {
#define HCI_OP_WRITE_INQUIRY_MODE 0x0c45
#define HCI_MAX_EIR_LENGTH 240
#define HCI_OP_WRITE_EIR 0x0c52
struct
hci_cp_write_eir
{
uint8_t
fec
;
uint8_t
data
[
HCI_MAX_EIR_LENGTH
];
}
__packed
;
#define HCI_OP_READ_SSP_MODE 0x0c55
struct
hci_rp_read_ssp_mode
{
__u8
status
;
...
...
@@ -611,6 +635,13 @@ struct hci_cp_write_ssp_mode {
__u8
mode
;
}
__packed
;
#define HCI_OP_READ_LOCAL_OOB_DATA 0x0c57
struct
hci_rp_read_local_oob_data
{
__u8
status
;
__u8
hash
[
16
];
__u8
randomizer
[
16
];
}
__packed
;
#define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58
#define HCI_OP_READ_LOCAL_VERSION 0x1001
...
...
@@ -745,7 +776,7 @@ struct hci_ev_auth_complete {
struct
hci_ev_remote_name
{
__u8
status
;
bdaddr_t
bdaddr
;
__u8
name
[
248
];
__u8
name
[
HCI_MAX_NAME_LENGTH
];
}
__packed
;
#define HCI_EV_ENCRYPT_CHANGE 0x08
...
...
@@ -953,6 +984,11 @@ struct hci_ev_user_confirm_req {
__le32
passkey
;
}
__packed
;
#define HCI_EV_REMOTE_OOB_DATA_REQUEST 0x35
struct
hci_ev_remote_oob_data_request
{
bdaddr_t
bdaddr
;
}
__packed
;
#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct
hci_ev_simple_pair_complete
{
__u8
status
;
...
...
include/net/bluetooth/hci_core.h
浏览文件 @
f3b3e36f
...
...
@@ -82,6 +82,13 @@ struct link_key {
u8
pin_len
;
};
struct
oob_data
{
struct
list_head
list
;
bdaddr_t
bdaddr
;
u8
hash
[
16
];
u8
randomizer
[
16
];
};
#define NUM_REASSEMBLY 4
struct
hci_dev
{
struct
list_head
list
;
...
...
@@ -94,7 +101,8 @@ struct hci_dev {
__u8
bus
;
__u8
dev_type
;
bdaddr_t
bdaddr
;
__u8
dev_name
[
248
];
__u8
dev_name
[
HCI_MAX_NAME_LENGTH
];
__u8
eir
[
HCI_MAX_EIR_LENGTH
];
__u8
dev_class
[
3
];
__u8
major_class
;
__u8
minor_class
;
...
...
@@ -169,6 +177,8 @@ struct hci_dev {
struct
list_head
link_keys
;
struct
list_head
remote_oob_data
;
struct
hci_dev_stats
stat
;
struct
sk_buff_head
driver_init
;
...
...
@@ -505,6 +515,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
u8
*
key
,
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
);
struct
oob_data
*
hci_find_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
int
hci_add_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
*
hash
,
u8
*
randomizer
);
int
hci_remove_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
);
void
hci_del_off_timer
(
struct
hci_dev
*
hdev
);
void
hci_event_packet
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
);
...
...
@@ -767,6 +784,12 @@ 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
);
int
mgmt_auth_failed
(
u16
index
,
bdaddr_t
*
bdaddr
,
u8
status
);
int
mgmt_set_local_name_complete
(
u16
index
,
u8
*
name
,
u8
status
);
int
mgmt_read_local_oob_data_reply_complete
(
u16
index
,
u8
*
hash
,
u8
*
randomizer
,
u8
status
);
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
);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk)
...
...
include/net/bluetooth/l2cap.h
浏览文件 @
f3b3e36f
...
...
@@ -280,7 +280,6 @@ struct l2cap_conn_param_update_rsp {
struct
l2cap_chan_list
{
struct
sock
*
head
;
rwlock_t
lock
;
long
num
;
};
struct
l2cap_conn
{
...
...
@@ -302,7 +301,6 @@ struct l2cap_conn {
struct
sk_buff
*
rx_skb
;
__u32
rx_len
;
__u8
rx_ident
;
__u8
tx_ident
;
__u8
disc_reason
;
...
...
include/net/bluetooth/mgmt.h
浏览文件 @
f3b3e36f
...
...
@@ -41,6 +41,10 @@ struct mgmt_rp_read_index_list {
__le16
index
[
0
];
}
__packed
;
/* Reserve one extra byte for names in management messages so that they
* are always guaranteed to be nul-terminated */
#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1)
#define MGMT_OP_READ_INFO 0x0004
struct
mgmt_rp_read_info
{
__u8
type
;
...
...
@@ -55,6 +59,7 @@ struct mgmt_rp_read_info {
__u16
manufacturer
;
__u8
hci_ver
;
__u16
hci_rev
;
__u8
name
[
MGMT_MAX_NAME_LENGTH
];
}
__packed
;
struct
mgmt_mode
{
...
...
@@ -167,6 +172,29 @@ struct mgmt_rp_user_confirm_reply {
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016
#define MGMT_OP_SET_LOCAL_NAME 0x0017
struct
mgmt_cp_set_local_name
{
__u8
name
[
MGMT_MAX_NAME_LENGTH
];
}
__packed
;
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018
struct
mgmt_rp_read_local_oob_data
{
__u8
hash
[
16
];
__u8
randomizer
[
16
];
}
__packed
;
#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0019
struct
mgmt_cp_add_remote_oob_data
{
bdaddr_t
bdaddr
;
__u8
hash
[
16
];
__u8
randomizer
[
16
];
}
__packed
;
#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x001A
struct
mgmt_cp_remove_remote_oob_data
{
bdaddr_t
bdaddr
;
}
__packed
;
#define MGMT_EV_CMD_COMPLETE 0x0001
struct
mgmt_ev_cmd_complete
{
__le16
opcode
;
...
...
@@ -234,3 +262,22 @@ struct mgmt_ev_auth_failed {
bdaddr_t
bdaddr
;
__u8
status
;
}
__packed
;
#define MGMT_EV_LOCAL_NAME_CHANGED 0x0011
struct
mgmt_ev_local_name_changed
{
__u8
name
[
MGMT_MAX_NAME_LENGTH
];
}
__packed
;
#define MGMT_EV_DEVICE_FOUND 0x0012
struct
mgmt_ev_device_found
{
bdaddr_t
bdaddr
;
__u8
dev_class
[
3
];
__s8
rssi
;
__u8
eir
[
HCI_MAX_EIR_LENGTH
];
}
__packed
;
#define MGMT_EV_REMOTE_NAME 0x0013
struct
mgmt_ev_remote_name
{
bdaddr_t
bdaddr
;
__u8
name
[
MGMT_MAX_NAME_LENGTH
];
}
__packed
;
net/bluetooth/bnep/bnep.h
浏览文件 @
f3b3e36f
...
...
@@ -23,88 +23,88 @@
#include <linux/crc32.h>
#include <net/bluetooth/bluetooth.h>
/
/ Limits
#define BNEP_MAX_PROTO_FILTERS
5
#define BNEP_MAX_MULTICAST_FILTERS
20
/
/ UUIDs
#define BNEP_BASE_UUID
0x0000000000001000800000805F9B34FB
#define BNEP_UUID16
0x02
#define BNEP_UUID32
0x04
#define BNEP_UUID128
0x16
#define BNEP_SVC_PANU
0x1115
#define BNEP_SVC_NAP
0x1116
#define BNEP_SVC_GN
0x1117
/
/ Packet types
#define BNEP_GENERAL
0x00
#define BNEP_CONTROL
0x01
#define BNEP_COMPRESSED
0x02
#define BNEP_COMPRESSED_SRC_ONLY
0x03
#define BNEP_COMPRESSED_DST_ONLY
0x04
/
/ Control types
#define BNEP_CMD_NOT_UNDERSTOOD
0x00
#define BNEP_SETUP_CONN_REQ
0x01
#define BNEP_SETUP_CONN_RSP
0x02
#define BNEP_FILTER_NET_TYPE_SET
0x03
#define BNEP_FILTER_NET_TYPE_RSP
0x04
#define BNEP_FILTER_MULTI_ADDR_SET
0x05
#define BNEP_FILTER_MULTI_ADDR_RSP
0x06
/
/ Extension types
#define BNEP_EXT_CONTROL
0x00
/
/ Response messages
#define BNEP_SUCCESS
0x00
#define BNEP_CONN_INVALID_DST
0x01
#define BNEP_CONN_INVALID_SRC
0x02
#define BNEP_CONN_INVALID_SVC
0x03
#define BNEP_CONN_NOT_ALLOWED
0x04
#define BNEP_FILTER_UNSUPPORTED_REQ
0x01
#define BNEP_FILTER_INVALID_RANGE
0x02
#define BNEP_FILTER_INVALID_MCADDR
0x02
#define BNEP_FILTER_LIMIT_REACHED
0x03
#define BNEP_FILTER_DENIED_SECURITY
0x04
/
/ L2CAP settings
#define BNEP_MTU
1691
#define BNEP_PSM
0x0f
#define BNEP_FLUSH_TO
0xffff
#define BNEP_CONNECT_TO
15
#define BNEP_FILTER_TO
15
/
/ Headers
#define BNEP_TYPE_MASK
0x7f
#define BNEP_EXT_HEADER
0x80
/
* Limits */
#define BNEP_MAX_PROTO_FILTERS
5
#define BNEP_MAX_MULTICAST_FILTERS
20
/
* UUIDs */
#define BNEP_BASE_UUID
0x0000000000001000800000805F9B34FB
#define BNEP_UUID16
0x02
#define BNEP_UUID32
0x04
#define BNEP_UUID128
0x16
#define BNEP_SVC_PANU
0x1115
#define BNEP_SVC_NAP
0x1116
#define BNEP_SVC_GN
0x1117
/
* Packet types */
#define BNEP_GENERAL
0x00
#define BNEP_CONTROL
0x01
#define BNEP_COMPRESSED
0x02
#define BNEP_COMPRESSED_SRC_ONLY
0x03
#define BNEP_COMPRESSED_DST_ONLY
0x04
/
* Control types */
#define BNEP_CMD_NOT_UNDERSTOOD
0x00
#define BNEP_SETUP_CONN_REQ
0x01
#define BNEP_SETUP_CONN_RSP
0x02
#define BNEP_FILTER_NET_TYPE_SET
0x03
#define BNEP_FILTER_NET_TYPE_RSP
0x04
#define BNEP_FILTER_MULTI_ADDR_SET
0x05
#define BNEP_FILTER_MULTI_ADDR_RSP
0x06
/
* Extension types */
#define BNEP_EXT_CONTROL 0x00
/
* Response messages */
#define BNEP_SUCCESS 0x00
#define BNEP_CONN_INVALID_DST 0x01
#define BNEP_CONN_INVALID_SRC 0x02
#define BNEP_CONN_INVALID_SVC 0x03
#define BNEP_CONN_NOT_ALLOWED 0x04
#define BNEP_FILTER_UNSUPPORTED_REQ
0x01
#define BNEP_FILTER_INVALID_RANGE
0x02
#define BNEP_FILTER_INVALID_MCADDR
0x02
#define BNEP_FILTER_LIMIT_REACHED
0x03
#define BNEP_FILTER_DENIED_SECURITY
0x04
/
* L2CAP settings */
#define BNEP_MTU
1691
#define BNEP_PSM 0x0f
#define BNEP_FLUSH_TO
0xffff
#define BNEP_CONNECT_TO
15
#define BNEP_FILTER_TO
15
/
* Headers */
#define BNEP_TYPE_MASK 0x7f
#define BNEP_EXT_HEADER 0x80
struct
bnep_setup_conn_req
{
__u8
type
;
__u8
ctrl
;
__u8
uuid_size
;
__u8
service
[
0
];
__u8
type
;
__u8
ctrl
;
__u8
uuid_size
;
__u8
service
[
0
];
}
__packed
;
struct
bnep_set_filter_req
{
__u8
type
;
__u8
ctrl
;
__u8
type
;
__u8
ctrl
;
__be16
len
;
__u8
list
[
0
];
__u8
list
[
0
];
}
__packed
;
struct
bnep_control_rsp
{
__u8
type
;
__u8
ctrl
;
__u8
type
;
__u8
ctrl
;
__be16
resp
;
}
__packed
;
struct
bnep_ext_hdr
{
__u8
type
;
__u8
len
;
__u8
data
[
0
];
__u8
type
;
__u8
len
;
__u8
data
[
0
];
}
__packed
;
/* BNEP ioctl defines */
...
...
@@ -114,10 +114,10 @@ struct bnep_ext_hdr {
#define BNEPGETCONNINFO _IOR('B', 211, int)
struct
bnep_connadd_req
{
int
sock
;
// Connected socket
int
sock
;
/* Connected socket */
__u32
flags
;
__u16
role
;
char
device
[
16
];
// Name of the Ethernet device
char
device
[
16
];
/* Name of the Ethernet device */
};
struct
bnep_conndel_req
{
...
...
@@ -148,14 +148,14 @@ int bnep_del_connection(struct bnep_conndel_req *req);
int
bnep_get_connlist
(
struct
bnep_connlist_req
*
req
);
int
bnep_get_conninfo
(
struct
bnep_conninfo
*
ci
);
/
/ BNEP sessions
/
* BNEP sessions */
struct
bnep_session
{
struct
list_head
list
;
unsigned
int
role
;
unsigned
long
state
;
unsigned
long
flags
;
atomic_t
killed
;
struct
task_struct
*
task
;
struct
ethhdr
eh
;
struct
msghdr
msg
;
...
...
@@ -173,7 +173,7 @@ void bnep_sock_cleanup(void);
static
inline
int
bnep_mc_hash
(
__u8
*
addr
)
{
return
(
crc32_be
(
~
0
,
addr
,
ETH_ALEN
)
>>
26
)
;
return
crc32_be
(
~
0
,
addr
,
ETH_ALEN
)
>>
26
;
}
#endif
net/bluetooth/bnep/core.c
浏览文件 @
f3b3e36f
...
...
@@ -36,6 +36,7 @@
#include <linux/errno.h>
#include <linux/net.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/socket.h>
...
...
@@ -131,7 +132,8 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len
return
-
EILSEQ
;
n
=
get_unaligned_be16
(
data
);
data
++
;
len
-=
2
;
data
++
;
len
-=
2
;
if
(
len
<
n
)
return
-
EILSEQ
;
...
...
@@ -176,7 +178,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
return
-
EILSEQ
;
n
=
get_unaligned_be16
(
data
);
data
+=
2
;
len
-=
2
;
data
+=
2
;
len
-=
2
;
if
(
len
<
n
)
return
-
EILSEQ
;
...
...
@@ -187,6 +190,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
n
/=
(
ETH_ALEN
*
2
);
if
(
n
>
0
)
{
int
i
;
s
->
mc_filter
=
0
;
/* Always send broadcast */
...
...
@@ -196,18 +201,22 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
for
(;
n
>
0
;
n
--
)
{
u8
a1
[
6
],
*
a2
;
memcpy
(
a1
,
data
,
ETH_ALEN
);
data
+=
ETH_ALEN
;
a2
=
data
;
data
+=
ETH_ALEN
;
memcpy
(
a1
,
data
,
ETH_ALEN
);
data
+=
ETH_ALEN
;
a2
=
data
;
data
+=
ETH_ALEN
;
BT_DBG
(
"mc filter %s -> %s"
,
batostr
((
void
*
)
a1
),
batostr
((
void
*
)
a2
));
#define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
/* Iterate from a1 to a2 */
set_bit
(
bnep_mc_hash
(
a1
),
(
ulong
*
)
&
s
->
mc_filter
);
while
(
memcmp
(
a1
,
a2
,
6
)
<
0
&&
s
->
mc_filter
!=
~
0LL
)
{
INCA
(
a1
);
/* Increment a1 */
i
=
5
;
while
(
i
>=
0
&&
++
a1
[
i
--
]
==
0
)
;
set_bit
(
bnep_mc_hash
(
a1
),
(
ulong
*
)
&
s
->
mc_filter
);
}
}
...
...
@@ -227,7 +236,8 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len)
u8
cmd
=
*
(
u8
*
)
data
;
int
err
=
0
;
data
++
;
len
--
;
data
++
;
len
--
;
switch
(
cmd
)
{
case
BNEP_CMD_NOT_UNDERSTOOD
:
...
...
@@ -302,7 +312,6 @@ static u8 __bnep_rx_hlen[] = {
ETH_ALEN
+
2
,
/* BNEP_COMPRESSED_SRC_ONLY */
ETH_ALEN
+
2
/* BNEP_COMPRESSED_DST_ONLY */
};
#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
static
inline
int
bnep_rx_frame
(
struct
bnep_session
*
s
,
struct
sk_buff
*
skb
)
{
...
...
@@ -312,9 +321,10 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
dev
->
stats
.
rx_bytes
+=
skb
->
len
;
type
=
*
(
u8
*
)
skb
->
data
;
skb_pull
(
skb
,
1
);
type
=
*
(
u8
*
)
skb
->
data
;
skb_pull
(
skb
,
1
);
if
((
type
&
BNEP_TYPE_MASK
)
>
BNEP_RX_TYPES
)
if
((
type
&
BNEP_TYPE_MASK
)
>
=
sizeof
(
__bnep_rx_hlen
)
)
goto
badframe
;
if
((
type
&
BNEP_TYPE_MASK
)
==
BNEP_CONTROL
)
{
...
...
@@ -367,14 +377,14 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
case
BNEP_COMPRESSED_DST_ONLY
:
memcpy
(
__skb_put
(
nskb
,
ETH_ALEN
),
skb_mac_header
(
skb
),
ETH_ALEN
);
ETH_ALEN
);
memcpy
(
__skb_put
(
nskb
,
ETH_ALEN
+
2
),
s
->
eh
.
h_source
,
ETH_ALEN
+
2
);
ETH_ALEN
+
2
);
break
;
case
BNEP_GENERAL
:
memcpy
(
__skb_put
(
nskb
,
ETH_ALEN
*
2
),
skb_mac_header
(
skb
),
ETH_ALEN
*
2
);
ETH_ALEN
*
2
);
put_unaligned
(
s
->
eh
.
h_proto
,
(
__be16
*
)
__skb_put
(
nskb
,
2
));
break
;
}
...
...
@@ -470,15 +480,14 @@ static int bnep_session(void *arg)
BT_DBG
(
""
);
daemonize
(
"kbnepd %s"
,
dev
->
name
);
set_user_nice
(
current
,
-
15
);
init_waitqueue_entry
(
&
wait
,
current
);
add_wait_queue
(
sk_sleep
(
sk
),
&
wait
);
while
(
!
atomic_read
(
&
s
->
killed
))
{
while
(
!
kthread_should_stop
(
))
{
set_current_state
(
TASK_INTERRUPTIBLE
);
/
/ RX
/
* RX */
while
((
skb
=
skb_dequeue
(
&
sk
->
sk_receive_queue
)))
{
skb_orphan
(
skb
);
bnep_rx_frame
(
s
,
skb
);
...
...
@@ -487,7 +496,7 @@ static int bnep_session(void *arg)
if
(
sk
->
sk_state
!=
BT_CONNECTED
)
break
;
/
/ TX
/
* TX */
while
((
skb
=
skb_dequeue
(
&
sk
->
sk_write_queue
)))
if
(
bnep_tx_frame
(
s
,
skb
))
break
;
...
...
@@ -555,8 +564,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
/* session struct allocated as private part of net_device */
dev
=
alloc_netdev
(
sizeof
(
struct
bnep_session
),
(
*
req
->
device
)
?
req
->
device
:
"bnep%d"
,
bnep_net_setup
);
(
*
req
->
device
)
?
req
->
device
:
"bnep%d"
,
bnep_net_setup
);
if
(
!
dev
)
return
-
ENOMEM
;
...
...
@@ -571,7 +580,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
s
=
netdev_priv
(
dev
);
/* This is rx header therefore addresses are swapped.
* ie eh.h_dest is our local address. */
* ie
.
eh.h_dest is our local address. */
memcpy
(
s
->
eh
.
h_dest
,
&
src
,
ETH_ALEN
);
memcpy
(
s
->
eh
.
h_source
,
&
dst
,
ETH_ALEN
);
memcpy
(
dev
->
dev_addr
,
s
->
eh
.
h_dest
,
ETH_ALEN
);
...
...
@@ -597,17 +606,17 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
SET_NETDEV_DEVTYPE
(
dev
,
&
bnep_type
);
err
=
register_netdev
(
dev
);
if
(
err
)
{
if
(
err
)
goto
failed
;
}
__bnep_link_session
(
s
);
err
=
kernel_thread
(
bnep_session
,
s
,
CLONE_KERNEL
);
if
(
err
<
0
)
{
s
->
task
=
kthread_run
(
bnep_session
,
s
,
"kbnepd %s"
,
dev
->
name
);
if
(
IS_ERR
(
s
->
task
)
)
{
/* Session thread start failed, gotta cleanup. */
unregister_netdev
(
dev
);
__bnep_unlink_session
(
s
);
err
=
PTR_ERR
(
s
->
task
);
goto
failed
;
}
...
...
@@ -631,15 +640,9 @@ int bnep_del_connection(struct bnep_conndel_req *req)
down_read
(
&
bnep_session_sem
);
s
=
__bnep_get_session
(
req
->
dst
);
if
(
s
)
{
/* Wakeup user-space which is polling for socket errors.
* This is temporary hack until we have shutdown in L2CAP */
s
->
sock
->
sk
->
sk_err
=
EUNATCH
;
/* Kill session thread */
atomic_inc
(
&
s
->
killed
);
wake_up_interruptible
(
sk_sleep
(
s
->
sock
->
sk
));
}
else
if
(
s
)
kthread_stop
(
s
->
task
);
else
err
=
-
ENOENT
;
up_read
(
&
bnep_session_sem
);
...
...
net/bluetooth/bnep/sock.c
浏览文件 @
f3b3e36f
...
...
@@ -39,10 +39,10 @@
#include <linux/init.h>
#include <linux/compat.h>
#include <linux/gfp.h>
#include <linux/uaccess.h>
#include <net/sock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "bnep.h"
...
...
net/bluetooth/cmtp/capi.c
浏览文件 @
f3b3e36f
...
...
@@ -35,6 +35,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/wait.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
...
...
@@ -143,7 +144,7 @@ static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
skb_queue_tail
(
&
session
->
transmit
,
skb
);
cmtp_schedule
(
session
);
wake_up_interruptible
(
sk_sleep
(
session
->
sock
->
sk
)
);
}
static
void
cmtp_send_interopmsg
(
struct
cmtp_session
*
session
,
...
...
@@ -386,8 +387,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
capi_ctr_down
(
ctrl
);
atomic_inc
(
&
session
->
terminate
);
cmtp_schedule
(
session
);
kthread_stop
(
session
->
task
);
}
static
void
cmtp_register_appl
(
struct
capi_ctr
*
ctrl
,
__u16
appl
,
capi_register_params
*
rp
)
...
...
net/bluetooth/cmtp/cmtp.h
浏览文件 @
f3b3e36f
...
...
@@ -37,7 +37,7 @@
#define CMTP_LOOPBACK 0
struct
cmtp_connadd_req
{
int
sock
;
/
/ Connected socket
int
sock
;
/
* Connected socket */
__u32
flags
;
};
...
...
@@ -81,7 +81,7 @@ struct cmtp_session {
char
name
[
BTNAMSIZ
];
atomic_t
terminate
;
struct
task_struct
*
task
;
wait_queue_head_t
wait
;
...
...
@@ -121,13 +121,6 @@ void cmtp_detach_device(struct cmtp_session *session);
void
cmtp_recv_capimsg
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
);
static
inline
void
cmtp_schedule
(
struct
cmtp_session
*
session
)
{
struct
sock
*
sk
=
session
->
sock
->
sk
;
wake_up_interruptible
(
sk_sleep
(
sk
));
}
/* CMTP init defines */
int
cmtp_init_sockets
(
void
);
void
cmtp_cleanup_sockets
(
void
);
...
...
net/bluetooth/cmtp/core.c
浏览文件 @
f3b3e36f
...
...
@@ -35,6 +35,7 @@
#include <linux/ioctl.h>
#include <linux/file.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
...
...
@@ -235,9 +236,12 @@ static void cmtp_process_transmit(struct cmtp_session *session)
size
=
min_t
(
uint
,
((
tail
<
258
)
?
(
tail
-
2
)
:
(
tail
-
3
)),
skb
->
len
);
if
((
scb
->
id
<
0
)
&&
((
scb
->
id
=
cmtp_alloc_block_id
(
session
))
<
0
))
{
skb_queue_head
(
&
session
->
transmit
,
skb
);
break
;
if
(
scb
->
id
<
0
)
{
scb
->
id
=
cmtp_alloc_block_id
(
session
);
if
(
scb
->
id
<
0
)
{
skb_queue_head
(
&
session
->
transmit
,
skb
);
break
;
}
}
if
(
size
<
256
)
{
...
...
@@ -284,12 +288,11 @@ static int cmtp_session(void *arg)
BT_DBG
(
"session %p"
,
session
);
daemonize
(
"kcmtpd_ctr_%d"
,
session
->
num
);
set_user_nice
(
current
,
-
15
);
init_waitqueue_entry
(
&
wait
,
current
);
add_wait_queue
(
sk_sleep
(
sk
),
&
wait
);
while
(
!
atomic_read
(
&
session
->
terminate
))
{
while
(
!
kthread_should_stop
(
))
{
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
sk
->
sk_state
!=
BT_CONNECTED
)
...
...
@@ -367,9 +370,12 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
__cmtp_link_session
(
session
);
err
=
kernel_thread
(
cmtp_session
,
session
,
CLONE_KERNEL
);
if
(
err
<
0
)
session
->
task
=
kthread_run
(
cmtp_session
,
session
,
"kcmtpd_ctr_%d"
,
session
->
num
);
if
(
IS_ERR
(
session
->
task
))
{
err
=
PTR_ERR
(
session
->
task
);
goto
unlink
;
}
if
(
!
(
session
->
flags
&
(
1
<<
CMTP_LOOPBACK
)))
{
err
=
cmtp_attach_device
(
session
);
...
...
@@ -406,9 +412,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req)
/* Flush the transmit queue */
skb_queue_purge
(
&
session
->
transmit
);
/* Kill session thread */
atomic_inc
(
&
session
->
terminate
);
cmtp_schedule
(
session
);
/* Stop session thread */
kthread_stop
(
session
->
task
);
}
else
err
=
-
ENOENT
;
...
...
net/bluetooth/cmtp/sock.c
浏览文件 @
f3b3e36f
...
...
@@ -34,12 +34,12 @@
#include <linux/file.h>
#include <linux/compat.h>
#include <linux/gfp.h>
#include <linux/uaccess.h>
#include <net/sock.h>
#include <linux/isdn/capilli.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "cmtp.h"
...
...
net/bluetooth/hci_core.c
浏览文件 @
f3b3e36f
...
...
@@ -56,7 +56,6 @@
static
void
hci_cmd_task
(
unsigned
long
arg
);
static
void
hci_rx_task
(
unsigned
long
arg
);
static
void
hci_tx_task
(
unsigned
long
arg
);
static
void
hci_notify
(
struct
hci_dev
*
hdev
,
int
event
);
static
DEFINE_RWLOCK
(
hci_task_lock
);
...
...
@@ -186,6 +185,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG
(
"%s %ld"
,
hdev
->
name
,
opt
);
/* Reset device */
set_bit
(
HCI_RESET
,
&
hdev
->
flags
);
hci_send_cmd
(
hdev
,
HCI_OP_RESET
,
0
,
NULL
);
}
...
...
@@ -213,8 +213,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Mandatory initialization */
/* Reset */
if
(
!
test_bit
(
HCI_QUIRK_NO_RESET
,
&
hdev
->
quirks
))
if
(
!
test_bit
(
HCI_QUIRK_NO_RESET
,
&
hdev
->
quirks
))
{
set_bit
(
HCI_RESET
,
&
hdev
->
flags
);
hci_send_cmd
(
hdev
,
HCI_OP_RESET
,
0
,
NULL
);
}
/* Read Local Supported Features */
hci_send_cmd
(
hdev
,
HCI_OP_READ_LOCAL_FEATURES
,
0
,
NULL
);
...
...
@@ -584,6 +586,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_req_cancel
(
hdev
,
ENODEV
);
hci_req_lock
(
hdev
);
/* Stop timer, it might be running */
del_timer_sync
(
&
hdev
->
cmd_timer
);
if
(
!
test_and_clear_bit
(
HCI_UP
,
&
hdev
->
flags
))
{
hci_req_unlock
(
hdev
);
return
0
;
...
...
@@ -623,7 +628,6 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Drop last sent command */
if
(
hdev
->
sent_cmd
)
{
del_timer_sync
(
&
hdev
->
cmd_timer
);
kfree_skb
(
hdev
->
sent_cmd
);
hdev
->
sent_cmd
=
NULL
;
}
...
...
@@ -1074,9 +1078,74 @@ static void hci_cmd_timer(unsigned long arg)
BT_ERR
(
"%s command tx timeout"
,
hdev
->
name
);
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
clear_bit
(
HCI_RESET
,
&
hdev
->
flags
);
tasklet_schedule
(
&
hdev
->
cmd_task
);
}
struct
oob_data
*
hci_find_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
)
{
struct
oob_data
*
data
;
list_for_each_entry
(
data
,
&
hdev
->
remote_oob_data
,
list
)
if
(
bacmp
(
bdaddr
,
&
data
->
bdaddr
)
==
0
)
return
data
;
return
NULL
;
}
int
hci_remove_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
)
{
struct
oob_data
*
data
;
data
=
hci_find_remote_oob_data
(
hdev
,
bdaddr
);
if
(
!
data
)
return
-
ENOENT
;
BT_DBG
(
"%s removing %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
list_del
(
&
data
->
list
);
kfree
(
data
);
return
0
;
}
int
hci_remote_oob_data_clear
(
struct
hci_dev
*
hdev
)
{
struct
oob_data
*
data
,
*
n
;
list_for_each_entry_safe
(
data
,
n
,
&
hdev
->
remote_oob_data
,
list
)
{
list_del
(
&
data
->
list
);
kfree
(
data
);
}
return
0
;
}
int
hci_add_remote_oob_data
(
struct
hci_dev
*
hdev
,
bdaddr_t
*
bdaddr
,
u8
*
hash
,
u8
*
randomizer
)
{
struct
oob_data
*
data
;
data
=
hci_find_remote_oob_data
(
hdev
,
bdaddr
);
if
(
!
data
)
{
data
=
kmalloc
(
sizeof
(
*
data
),
GFP_ATOMIC
);
if
(
!
data
)
return
-
ENOMEM
;
bacpy
(
&
data
->
bdaddr
,
bdaddr
);
list_add
(
&
data
->
list
,
&
hdev
->
remote_oob_data
);
}
memcpy
(
data
->
hash
,
hash
,
sizeof
(
data
->
hash
));
memcpy
(
data
->
randomizer
,
randomizer
,
sizeof
(
data
->
randomizer
));
BT_DBG
(
"%s for %s"
,
hdev
->
name
,
batostr
(
bdaddr
));
return
0
;
}
/* Register HCI device */
int
hci_register_dev
(
struct
hci_dev
*
hdev
)
{
...
...
@@ -1141,6 +1210,8 @@ int hci_register_dev(struct hci_dev *hdev)
INIT_LIST_HEAD
(
&
hdev
->
link_keys
);
INIT_LIST_HEAD
(
&
hdev
->
remote_oob_data
);
INIT_WORK
(
&
hdev
->
power_on
,
hci_power_on
);
INIT_WORK
(
&
hdev
->
power_off
,
hci_power_off
);
setup_timer
(
&
hdev
->
off_timer
,
hci_auto_off
,
(
unsigned
long
)
hdev
);
...
...
@@ -1220,6 +1291,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_blacklist_clear
(
hdev
);
hci_uuids_clear
(
hdev
);
hci_link_keys_clear
(
hdev
);
hci_remote_oob_data_clear
(
hdev
);
hci_dev_unlock_bh
(
hdev
);
__hci_dev_put
(
hdev
);
...
...
@@ -1269,7 +1341,7 @@ int hci_recv_frame(struct sk_buff *skb)
EXPORT_SYMBOL
(
hci_recv_frame
);
static
int
hci_reassembly
(
struct
hci_dev
*
hdev
,
int
type
,
void
*
data
,
int
count
,
__u8
index
,
gfp_t
gfp_mask
)
int
count
,
__u8
index
)
{
int
len
=
0
;
int
hlen
=
0
;
...
...
@@ -1299,7 +1371,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
break
;
}
skb
=
bt_skb_alloc
(
len
,
gfp_mask
);
skb
=
bt_skb_alloc
(
len
,
GFP_ATOMIC
);
if
(
!
skb
)
return
-
ENOMEM
;
...
...
@@ -1385,8 +1457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
return
-
EILSEQ
;
while
(
count
)
{
rem
=
hci_reassembly
(
hdev
,
type
,
data
,
count
,
type
-
1
,
GFP_ATOMIC
);
rem
=
hci_reassembly
(
hdev
,
type
,
data
,
count
,
type
-
1
);
if
(
rem
<
0
)
return
rem
;
...
...
@@ -1420,8 +1491,8 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
}
else
type
=
bt_cb
(
skb
)
->
pkt_type
;
rem
=
hci_reassembly
(
hdev
,
type
,
data
,
count
,
STREAM_REASSEMBLY
,
GFP_ATOMIC
);
rem
=
hci_reassembly
(
hdev
,
type
,
data
,
count
,
STREAM_REASSEMBLY
);
if
(
rem
<
0
)
return
rem
;
...
...
net/bluetooth/hci_event.c
浏览文件 @
f3b3e36f
...
...
@@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
clear_bit
(
HCI_RESET
,
&
hdev
->
flags
);
hci_req_complete
(
hdev
,
HCI_OP_RESET
,
status
);
}
...
...
@@ -193,14 +195,17 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
if
(
status
)
return
;
sent
=
hci_sent_cmd_data
(
hdev
,
HCI_OP_WRITE_LOCAL_NAME
);
if
(
!
sent
)
return
;
memcpy
(
hdev
->
dev_name
,
sent
,
248
);
if
(
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
mgmt_set_local_name_complete
(
hdev
->
id
,
sent
,
status
);
if
(
status
)
return
;
memcpy
(
hdev
->
dev_name
,
sent
,
HCI_MAX_NAME_LENGTH
);
}
static
void
hci_cc_read_local_name
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
...
...
@@ -212,7 +217,7 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
if
(
rp
->
status
)
return
;
memcpy
(
hdev
->
dev_name
,
rp
->
name
,
248
);
memcpy
(
hdev
->
dev_name
,
rp
->
name
,
HCI_MAX_NAME_LENGTH
);
}
static
void
hci_cc_write_auth_enable
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
...
...
@@ -819,6 +824,17 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
rp
->
status
);
}
static
void
hci_cc_read_local_oob_data_reply
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_rp_read_local_oob_data
*
rp
=
(
void
*
)
skb
->
data
;
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
rp
->
status
);
mgmt_read_local_oob_data_reply_complete
(
hdev
->
id
,
rp
->
hash
,
rp
->
randomizer
,
rp
->
status
);
}
static
inline
void
hci_cs_inquiry
(
struct
hci_dev
*
hdev
,
__u8
status
)
{
BT_DBG
(
"%s status 0x%x"
,
hdev
->
name
,
status
);
...
...
@@ -1212,7 +1228,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock
(
hdev
);
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
,
info
++
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
...
...
@@ -1221,8 +1237,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data
.
clock_offset
=
info
->
clock_offset
;
data
.
rssi
=
0x00
;
data
.
ssp_mode
=
0x00
;
info
++
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
->
id
,
&
info
->
bdaddr
,
info
->
dev_class
,
0
,
NULL
);
}
hci_dev_unlock
(
hdev
);
...
...
@@ -1480,6 +1497,9 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
hci_dev_lock
(
hdev
);
if
(
ev
->
status
==
0
&&
test_bit
(
HCI_MGMT
,
&
hdev
->
flags
))
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
))
{
struct
hci_cp_auth_requested
cp
;
...
...
@@ -1749,6 +1769,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_pin_code_neg_reply
(
hdev
,
skb
);
break
;
case
HCI_OP_READ_LOCAL_OOB_DATA
:
hci_cc_read_local_oob_data_reply
(
hdev
,
skb
);
break
;
case
HCI_OP_LE_READ_BUFFER_SIZE
:
hci_cc_le_read_buffer_size
(
hdev
,
skb
);
break
;
...
...
@@ -1847,7 +1871,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
if
(
ev
->
opcode
!=
HCI_OP_NOP
)
del_timer
(
&
hdev
->
cmd_timer
);
if
(
ev
->
ncmd
)
{
if
(
ev
->
ncmd
&&
!
test_bit
(
HCI_RESET
,
&
hdev
->
flags
)
)
{
atomic_set
(
&
hdev
->
cmd_cnt
,
1
);
if
(
!
skb_queue_empty
(
&
hdev
->
cmd_q
))
tasklet_schedule
(
&
hdev
->
cmd_task
);
...
...
@@ -2138,7 +2162,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
struct
inquiry_info_with_rssi_and_pscan_mode
*
info
;
info
=
(
void
*
)
(
skb
->
data
+
1
);
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
,
info
++
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
...
...
@@ -2147,13 +2171,15 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data
.
clock_offset
=
info
->
clock_offset
;
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x00
;
info
++
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
->
id
,
&
info
->
bdaddr
,
info
->
dev_class
,
info
->
rssi
,
NULL
);
}
}
else
{
struct
inquiry_info_with_rssi
*
info
=
(
void
*
)
(
skb
->
data
+
1
);
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
,
info
++
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
...
...
@@ -2162,8 +2188,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data
.
clock_offset
=
info
->
clock_offset
;
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x00
;
info
++
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
->
id
,
&
info
->
bdaddr
,
info
->
dev_class
,
info
->
rssi
,
NULL
);
}
}
...
...
@@ -2294,7 +2322,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
hci_dev_lock
(
hdev
);
for
(;
num_rsp
;
num_rsp
--
)
{
for
(;
num_rsp
;
num_rsp
--
,
info
++
)
{
bacpy
(
&
data
.
bdaddr
,
&
info
->
bdaddr
);
data
.
pscan_rep_mode
=
info
->
pscan_rep_mode
;
data
.
pscan_period_mode
=
info
->
pscan_period_mode
;
...
...
@@ -2303,8 +2331,9 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
data
.
clock_offset
=
info
->
clock_offset
;
data
.
rssi
=
info
->
rssi
;
data
.
ssp_mode
=
0x01
;
info
++
;
hci_inquiry_cache_update
(
hdev
,
&
data
);
mgmt_device_found
(
hdev
->
id
,
&
info
->
bdaddr
,
info
->
dev_class
,
info
->
rssi
,
info
->
data
);
}
hci_dev_unlock
(
hdev
);
...
...
@@ -2353,9 +2382,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
bacpy
(
&
cp
.
bdaddr
,
&
ev
->
bdaddr
);
cp
.
capability
=
conn
->
io_capability
;
cp
.
oob_data
=
0
;
cp
.
authentication
=
hci_get_auth_req
(
conn
);
if
((
conn
->
out
==
0x01
||
conn
->
remote_oob
==
0x01
)
&&
hci_find_remote_oob_data
(
hdev
,
&
conn
->
dst
))
cp
.
oob_data
=
0x01
;
else
cp
.
oob_data
=
0x00
;
hci_send_cmd
(
hdev
,
HCI_OP_IO_CAPABILITY_REPLY
,
sizeof
(
cp
),
&
cp
);
}
else
{
...
...
@@ -2453,6 +2487,37 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_remote_oob_data_request_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_remote_oob_data_request
*
ev
=
(
void
*
)
skb
->
data
;
struct
oob_data
*
data
;
BT_DBG
(
"%s"
,
hdev
->
name
);
hci_dev_lock
(
hdev
);
data
=
hci_find_remote_oob_data
(
hdev
,
&
ev
->
bdaddr
);
if
(
data
)
{
struct
hci_cp_remote_oob_data_reply
cp
;
bacpy
(
&
cp
.
bdaddr
,
&
ev
->
bdaddr
);
memcpy
(
cp
.
hash
,
data
->
hash
,
sizeof
(
cp
.
hash
));
memcpy
(
cp
.
randomizer
,
data
->
randomizer
,
sizeof
(
cp
.
randomizer
));
hci_send_cmd
(
hdev
,
HCI_OP_REMOTE_OOB_DATA_REPLY
,
sizeof
(
cp
),
&
cp
);
}
else
{
struct
hci_cp_remote_oob_data_neg_reply
cp
;
bacpy
(
&
cp
.
bdaddr
,
&
ev
->
bdaddr
);
hci_send_cmd
(
hdev
,
HCI_OP_REMOTE_OOB_DATA_NEG_REPLY
,
sizeof
(
cp
),
&
cp
);
}
hci_dev_unlock
(
hdev
);
}
static
inline
void
hci_le_conn_complete_evt
(
struct
hci_dev
*
hdev
,
struct
sk_buff
*
skb
)
{
struct
hci_ev_le_conn_complete
*
ev
=
(
void
*
)
skb
->
data
;
...
...
@@ -2655,6 +2720,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_le_meta_evt
(
hdev
,
skb
);
break
;
case
HCI_EV_REMOTE_OOB_DATA_REQUEST
:
hci_remote_oob_data_request_evt
(
hdev
,
skb
);
break
;
default:
BT_DBG
(
"%s event 0x%x"
,
hdev
->
name
,
event
);
break
;
...
...
net/bluetooth/hci_sysfs.c
浏览文件 @
f3b3e36f
...
...
@@ -216,13 +216,13 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char
static
ssize_t
show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
char
name
[
249
];
char
name
[
HCI_MAX_NAME_LENGTH
+
1
];
int
i
;
for
(
i
=
0
;
i
<
248
;
i
++
)
for
(
i
=
0
;
i
<
HCI_MAX_NAME_LENGTH
;
i
++
)
name
[
i
]
=
hdev
->
dev_name
[
i
];
name
[
248
]
=
'\0'
;
name
[
HCI_MAX_NAME_LENGTH
]
=
'\0'
;
return
sprintf
(
buf
,
"%s
\n
"
,
name
);
}
...
...
@@ -277,10 +277,12 @@ static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *at
static
ssize_t
store_idle_timeout
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
unsigned
long
val
;
unsigned
int
val
;
int
rv
;
if
(
strict_strtoul
(
buf
,
0
,
&
val
)
<
0
)
return
-
EINVAL
;
rv
=
kstrtouint
(
buf
,
0
,
&
val
);
if
(
rv
<
0
)
return
rv
;
if
(
val
!=
0
&&
(
val
<
500
||
val
>
3600000
))
return
-
EINVAL
;
...
...
@@ -299,15 +301,14 @@ static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribu
static
ssize_t
store_sniff_max_interval
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
unsigned
long
val
;
if
(
strict_strtoul
(
buf
,
0
,
&
val
)
<
0
)
return
-
EINVAL
;
u16
val
;
int
rv
;
if
(
val
<
0x0002
||
val
>
0xFFFE
||
val
%
2
)
return
-
EINVAL
;
rv
=
kstrtou16
(
buf
,
0
,
&
val
);
if
(
rv
<
0
)
return
rv
;
if
(
val
<
hdev
->
sniff_min_interval
)
if
(
val
==
0
||
val
%
2
||
val
<
hdev
->
sniff_min_interval
)
return
-
EINVAL
;
hdev
->
sniff_max_interval
=
val
;
...
...
@@ -324,15 +325,14 @@ static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribu
static
ssize_t
store_sniff_min_interval
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
unsigned
long
val
;
u16
val
;
int
rv
;
if
(
strict_strtoul
(
buf
,
0
,
&
val
)
<
0
)
return
-
EINVAL
;
if
(
val
<
0x0002
||
val
>
0xFFFE
||
val
%
2
)
return
-
EINVAL
;
rv
=
kstrtou16
(
buf
,
0
,
&
val
);
if
(
rv
<
0
)
return
rv
;
if
(
val
>
hdev
->
sniff_max_interval
)
if
(
val
==
0
||
val
%
2
||
val
>
hdev
->
sniff_max_interval
)
return
-
EINVAL
;
hdev
->
sniff_min_interval
=
val
;
...
...
net/bluetooth/hidp/core.c
浏览文件 @
f3b3e36f
...
...
@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <linux/input.h>
...
...
@@ -55,22 +56,24 @@ static DECLARE_RWSEM(hidp_session_sem);
static
LIST_HEAD
(
hidp_session_list
);
static
unsigned
char
hidp_keycode
[
256
]
=
{
0
,
0
,
0
,
0
,
30
,
48
,
46
,
32
,
18
,
33
,
34
,
35
,
23
,
36
,
37
,
38
,
50
,
49
,
24
,
25
,
16
,
19
,
31
,
20
,
22
,
47
,
17
,
45
,
21
,
44
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
28
,
1
,
14
,
15
,
57
,
12
,
13
,
26
,
27
,
43
,
43
,
39
,
40
,
41
,
51
,
52
,
53
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
87
,
88
,
99
,
70
,
119
,
110
,
102
,
104
,
111
,
107
,
109
,
106
,
105
,
108
,
103
,
69
,
98
,
55
,
74
,
78
,
96
,
79
,
80
,
81
,
75
,
76
,
77
,
71
,
72
,
73
,
82
,
83
,
86
,
127
,
116
,
117
,
183
,
184
,
185
,
186
,
187
,
188
,
189
,
190
,
191
,
192
,
193
,
194
,
134
,
138
,
130
,
132
,
128
,
129
,
131
,
137
,
133
,
135
,
136
,
113
,
115
,
114
,
0
,
0
,
0
,
121
,
0
,
89
,
93
,
124
,
92
,
94
,
95
,
0
,
0
,
0
,
122
,
123
,
90
,
91
,
85
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
29
,
42
,
56
,
125
,
97
,
54
,
100
,
126
,
164
,
166
,
165
,
163
,
161
,
115
,
114
,
113
,
150
,
158
,
159
,
128
,
136
,
177
,
178
,
176
,
142
,
152
,
173
,
140
0
,
0
,
0
,
0
,
30
,
48
,
46
,
32
,
18
,
33
,
34
,
35
,
23
,
36
,
37
,
38
,
50
,
49
,
24
,
25
,
16
,
19
,
31
,
20
,
22
,
47
,
17
,
45
,
21
,
44
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
28
,
1
,
14
,
15
,
57
,
12
,
13
,
26
,
27
,
43
,
43
,
39
,
40
,
41
,
51
,
52
,
53
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
87
,
88
,
99
,
70
,
119
,
110
,
102
,
104
,
111
,
107
,
109
,
106
,
105
,
108
,
103
,
69
,
98
,
55
,
74
,
78
,
96
,
79
,
80
,
81
,
75
,
76
,
77
,
71
,
72
,
73
,
82
,
83
,
86
,
127
,
116
,
117
,
183
,
184
,
185
,
186
,
187
,
188
,
189
,
190
,
191
,
192
,
193
,
194
,
134
,
138
,
130
,
132
,
128
,
129
,
131
,
137
,
133
,
135
,
136
,
113
,
115
,
114
,
0
,
0
,
0
,
121
,
0
,
89
,
93
,
124
,
92
,
94
,
95
,
0
,
0
,
0
,
122
,
123
,
90
,
91
,
85
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
29
,
42
,
56
,
125
,
97
,
54
,
100
,
126
,
164
,
166
,
165
,
163
,
161
,
115
,
114
,
113
,
150
,
158
,
159
,
128
,
136
,
177
,
178
,
176
,
142
,
152
,
173
,
140
};
static
unsigned
char
hidp_mkeyspat
[]
=
{
0x01
,
0x01
,
0x01
,
0x01
,
0x01
,
0x01
};
...
...
@@ -461,8 +464,7 @@ static void hidp_idle_timeout(unsigned long arg)
{
struct
hidp_session
*
session
=
(
struct
hidp_session
*
)
arg
;
atomic_inc
(
&
session
->
terminate
);
hidp_schedule
(
session
);
kthread_stop
(
session
->
task
);
}
static
void
hidp_set_timer
(
struct
hidp_session
*
session
)
...
...
@@ -533,9 +535,7 @@ static void hidp_process_hid_control(struct hidp_session *session,
skb_queue_purge
(
&
session
->
ctrl_transmit
);
skb_queue_purge
(
&
session
->
intr_transmit
);
/* Kill session thread */
atomic_inc
(
&
session
->
terminate
);
hidp_schedule
(
session
);
kthread_stop
(
session
->
task
);
}
}
...
...
@@ -694,22 +694,10 @@ static int hidp_session(void *arg)
struct
sock
*
ctrl_sk
=
session
->
ctrl_sock
->
sk
;
struct
sock
*
intr_sk
=
session
->
intr_sock
->
sk
;
struct
sk_buff
*
skb
;
int
vendor
=
0x0000
,
product
=
0x0000
;
wait_queue_t
ctrl_wait
,
intr_wait
;
BT_DBG
(
"session %p"
,
session
);
if
(
session
->
input
)
{
vendor
=
session
->
input
->
id
.
vendor
;
product
=
session
->
input
->
id
.
product
;
}
if
(
session
->
hid
)
{
vendor
=
session
->
hid
->
vendor
;
product
=
session
->
hid
->
product
;
}
daemonize
(
"khidpd_%04x%04x"
,
vendor
,
product
);
set_user_nice
(
current
,
-
15
);
init_waitqueue_entry
(
&
ctrl_wait
,
current
);
...
...
@@ -718,10 +706,11 @@ static int hidp_session(void *arg)
add_wait_queue
(
sk_sleep
(
intr_sk
),
&
intr_wait
);
session
->
waiting_for_startup
=
0
;
wake_up_interruptible
(
&
session
->
startup_queue
);
while
(
!
atomic_read
(
&
session
->
terminate
))
{
while
(
!
kthread_should_stop
(
))
{
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
ctrl_sk
->
sk_state
!=
BT_CONNECTED
||
intr_sk
->
sk_state
!=
BT_CONNECTED
)
if
(
ctrl_sk
->
sk_state
!=
BT_CONNECTED
||
intr_sk
->
sk_state
!=
BT_CONNECTED
)
break
;
while
((
skb
=
skb_dequeue
(
&
ctrl_sk
->
sk_receive_queue
)))
{
...
...
@@ -965,6 +954,7 @@ static int hidp_setup_hid(struct hidp_session *session,
int
hidp_add_connection
(
struct
hidp_connadd_req
*
req
,
struct
socket
*
ctrl_sock
,
struct
socket
*
intr_sock
)
{
struct
hidp_session
*
session
,
*
s
;
int
vendor
,
product
;
int
err
;
BT_DBG
(
""
);
...
...
@@ -1026,9 +1016,24 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
hidp_set_timer
(
session
);
err
=
kernel_thread
(
hidp_session
,
session
,
CLONE_KERNEL
);
if
(
err
<
0
)
if
(
session
->
hid
)
{
vendor
=
session
->
hid
->
vendor
;
product
=
session
->
hid
->
product
;
}
else
if
(
session
->
input
)
{
vendor
=
session
->
input
->
id
.
vendor
;
product
=
session
->
input
->
id
.
product
;
}
else
{
vendor
=
0x0000
;
product
=
0x0000
;
}
session
->
task
=
kthread_run
(
hidp_session
,
session
,
"khidpd_%04x%04x"
,
vendor
,
product
);
if
(
IS_ERR
(
session
->
task
))
{
err
=
PTR_ERR
(
session
->
task
);
goto
unlink
;
}
while
(
session
->
waiting_for_startup
)
{
wait_event_interruptible
(
session
->
startup_queue
,
!
session
->
waiting_for_startup
);
...
...
@@ -1053,8 +1058,7 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
err_add_device:
hid_destroy_device
(
session
->
hid
);
session
->
hid
=
NULL
;
atomic_inc
(
&
session
->
terminate
);
hidp_schedule
(
session
);
kthread_stop
(
session
->
task
);
unlink:
hidp_del_timer
(
session
);
...
...
@@ -1105,13 +1109,7 @@ int hidp_del_connection(struct hidp_conndel_req *req)
skb_queue_purge
(
&
session
->
ctrl_transmit
);
skb_queue_purge
(
&
session
->
intr_transmit
);
/* Wakeup user-space polling for socket errors */
session
->
intr_sock
->
sk
->
sk_err
=
EUNATCH
;
session
->
ctrl_sock
->
sk
->
sk_err
=
EUNATCH
;
/* Kill session thread */
atomic_inc
(
&
session
->
terminate
);
hidp_schedule
(
session
);
kthread_stop
(
session
->
task
);
}
}
else
err
=
-
ENOENT
;
...
...
net/bluetooth/hidp/hidp.h
浏览文件 @
f3b3e36f
...
...
@@ -84,8 +84,8 @@
#define HIDP_WAITING_FOR_SEND_ACK 11
struct
hidp_connadd_req
{
int
ctrl_sock
;
/
/ Connected control socket
int
intr_sock
;
/
/ Connteted interrupt socket
int
ctrl_sock
;
/
* Connected control socket */
int
intr_sock
;
/
* Connected interrupt socket */
__u16
parser
;
__u16
rd_size
;
__u8
__user
*
rd_data
;
...
...
@@ -142,7 +142,7 @@ struct hidp_session {
uint
ctrl_mtu
;
uint
intr_mtu
;
atomic_t
terminate
;
struct
task_struct
*
task
;
unsigned
char
keys
[
8
];
unsigned
char
leds
;
...
...
net/bluetooth/hidp/sock.c
浏览文件 @
f3b3e36f
...
...
@@ -85,7 +85,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
return
err
;
}
if
(
csock
->
sk
->
sk_state
!=
BT_CONNECTED
||
isock
->
sk
->
sk_state
!=
BT_CONNECTED
)
{
if
(
csock
->
sk
->
sk_state
!=
BT_CONNECTED
||
isock
->
sk
->
sk_state
!=
BT_CONNECTED
)
{
sockfd_put
(
csock
);
sockfd_put
(
isock
);
return
-
EBADFD
;
...
...
@@ -140,8 +141,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
#ifdef CONFIG_COMPAT
struct
compat_hidp_connadd_req
{
int
ctrl_sock
;
/
/ Connected control socket
int
intr_sock
;
/
/ Connteted interrupt socket
int
ctrl_sock
;
/
* Connected control socket */
int
intr_sock
;
/
* Connected interrupt socket */
__u16
parser
;
__u16
rd_size
;
compat_uptr_t
rd_data
;
...
...
net/bluetooth/l2cap_core.c
浏览文件 @
f3b3e36f
...
...
@@ -169,7 +169,7 @@ static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
__sock_put
(
sk
);
}
static
void
__l2cap_chan_add
(
struct
l2cap_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
)
static
void
__l2cap_chan_add
(
struct
l2cap_conn
*
conn
,
struct
sock
*
sk
)
{
struct
l2cap_chan_list
*
l
=
&
conn
->
chan_list
;
...
...
@@ -204,9 +204,6 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
}
__l2cap_chan_link
(
l
,
sk
);
if
(
parent
)
bt_accept_enqueue
(
parent
,
sk
);
}
/* Delete channel.
...
...
@@ -652,7 +649,9 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
bacpy
(
&
bt_sk
(
sk
)
->
src
,
conn
->
src
);
bacpy
(
&
bt_sk
(
sk
)
->
dst
,
conn
->
dst
);
__l2cap_chan_add
(
conn
,
sk
,
parent
);
bt_accept_enqueue
(
parent
,
sk
);
__l2cap_chan_add
(
conn
,
sk
);
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
...
...
@@ -793,11 +792,11 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree
(
conn
);
}
static
inline
void
l2cap_chan_add
(
struct
l2cap_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
)
static
inline
void
l2cap_chan_add
(
struct
l2cap_conn
*
conn
,
struct
sock
*
sk
)
{
struct
l2cap_chan_list
*
l
=
&
conn
->
chan_list
;
write_lock_bh
(
&
l
->
lock
);
__l2cap_chan_add
(
conn
,
sk
,
parent
);
__l2cap_chan_add
(
conn
,
sk
);
write_unlock_bh
(
&
l
->
lock
);
}
...
...
@@ -876,7 +875,7 @@ int l2cap_do_connect(struct sock *sk)
/* Update source addr of the socket */
bacpy
(
src
,
conn
->
src
);
l2cap_chan_add
(
conn
,
sk
,
NULL
);
l2cap_chan_add
(
conn
,
sk
);
sk
->
sk_state
=
BT_CONNECT
;
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
...
...
@@ -1116,7 +1115,9 @@ int l2cap_ertm_send(struct sock *sk)
bt_cb
(
skb
)
->
tx_seq
=
pi
->
next_tx_seq
;
pi
->
next_tx_seq
=
(
pi
->
next_tx_seq
+
1
)
%
64
;
pi
->
unacked_frames
++
;
if
(
bt_cb
(
skb
)
->
retries
==
1
)
pi
->
unacked_frames
++
;
pi
->
frames_sent
++
;
if
(
skb_queue_is_last
(
TX_QUEUE
(
sk
),
skb
))
...
...
@@ -2030,7 +2031,9 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_pi
(
sk
)
->
psm
=
psm
;
l2cap_pi
(
sk
)
->
dcid
=
scid
;
__l2cap_chan_add
(
conn
,
sk
,
parent
);
bt_accept_enqueue
(
parent
,
sk
);
__l2cap_chan_add
(
conn
,
sk
);
dcid
=
l2cap_pi
(
sk
)
->
scid
;
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
...
...
@@ -2460,6 +2463,11 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
BT_DBG
(
"type 0x%4.4x result 0x%2.2x"
,
type
,
result
);
/* L2CAP Info req/rsp are unbound to channels, add extra checks */
if
(
cmd
->
ident
!=
conn
->
info_ident
||
conn
->
info_state
&
L2CAP_INFO_FEAT_MASK_REQ_DONE
)
return
0
;
del_timer
(
&
conn
->
info_timer
);
if
(
result
!=
L2CAP_IR_SUCCESS
)
{
...
...
@@ -2670,7 +2678,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn,
if
(
err
)
{
struct
l2cap_cmd_rej
rej
;
BT_DBG
(
"error %d"
,
err
);
BT_ERR
(
"Wrong link type (%d)"
,
err
);
/* FIXME: Map err to a valid reason */
rej
.
reason
=
cpu_to_le16
(
0
);
...
...
net/bluetooth/l2cap_sock.c
浏览文件 @
f3b3e36f
...
...
@@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason)
rsp
.
status
=
cpu_to_le16
(
L2CAP_CS_NO_INFO
);
l2cap_send_cmd
(
conn
,
l2cap_pi
(
sk
)
->
ident
,
L2CAP_CONN_RSP
,
sizeof
(
rsp
),
&
rsp
);
}
else
l2cap_chan_del
(
sk
,
reason
);
}
l2cap_chan_del
(
sk
,
reason
);
break
;
case
BT_CONNECT
:
...
...
net/bluetooth/mgmt.c
浏览文件 @
f3b3e36f
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录