Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
f3b3e36f
Commit
f3b3e36f
authored
Apr 07, 2011
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6
parents
b0006e69
db940cb0
Changes
21
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
981 additions
and
291 deletions
+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
No files found.
drivers/bluetooth/btusb.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
f3b3e36f
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment