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
nexedi
linux
Commits
1cdd77fe
Commit
1cdd77fe
authored
Jan 09, 2005
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-mh.bkbits.net/bluetooth-2.6
into nuts.davemloft.net:/disk1/BK/net-2.6
parents
e0512113
0d8b93d0
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
384 additions
and
126 deletions
+384
-126
drivers/bluetooth/bcm203x.c
drivers/bluetooth/bcm203x.c
+6
-2
drivers/bluetooth/bfusb.c
drivers/bluetooth/bfusb.c
+8
-0
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_bcsp.c
+2
-2
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ldisc.c
+11
-2
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.c
+11
-2
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_core.h
+0
-2
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+8
-19
include/net/bluetooth/rfcomm.h
include/net/bluetooth/rfcomm.h
+20
-30
include/net/bluetooth/sco.h
include/net/bluetooth/sco.h
+4
-3
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/capi.c
+13
-15
net/bluetooth/cmtp/cmtp.h
net/bluetooth/cmtp/cmtp.h
+0
-1
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+1
-1
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+2
-2
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+5
-5
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+153
-17
net/bluetooth/hidp/hidp.h
net/bluetooth/hidp/hidp.h
+45
-0
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+12
-8
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+31
-8
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+49
-5
net/bluetooth/sco.c
net/bluetooth/sco.c
+3
-2
No files found.
drivers/bluetooth/bcm203x.c
View file @
1cdd77fe
...
...
@@ -46,6 +46,8 @@
#define VERSION "1.0"
static
int
ignore
=
0
;
static
struct
usb_device_id
bcm203x_table
[]
=
{
/* Broadcom Blutonium (BCM2033) */
{
USB_DEVICE
(
0x0a5c
,
0x2033
)
},
...
...
@@ -55,7 +57,6 @@ static struct usb_device_id bcm203x_table[] = {
MODULE_DEVICE_TABLE
(
usb
,
bcm203x_table
);
#define BCM203X_ERROR 0
#define BCM203X_RESET 1
#define BCM203X_LOAD_MINIDRV 2
...
...
@@ -175,7 +176,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
BT_DBG
(
"intf %p id %p"
,
intf
,
id
);
if
(
i
ntf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
if
(
i
gnore
||
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
)
return
-
ENODEV
;
data
=
kmalloc
(
sizeof
(
*
data
),
GFP_KERNEL
);
...
...
@@ -304,6 +305,9 @@ static void __exit bcm203x_exit(void)
module_init
(
bcm203x_init
);
module_exit
(
bcm203x_exit
);
module_param
(
ignore
,
bool
,
0644
);
MODULE_PARM_DESC
(
ignore
,
"Ignore devices from the matching table"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Broadcom Blutonium firmware driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
drivers/bluetooth/bfusb.c
View file @
1cdd77fe
...
...
@@ -47,6 +47,8 @@
#define VERSION "1.1"
static
int
ignore
=
0
;
static
struct
usb_driver
bfusb_driver
;
static
struct
usb_device_id
bfusb_table
[]
=
{
...
...
@@ -655,6 +657,9 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
BT_DBG
(
"intf %p id %p"
,
intf
,
id
);
if
(
ignore
)
return
-
ENODEV
;
/* Check number of endpoints */
if
(
intf
->
cur_altsetting
->
desc
.
bNumEndpoints
<
2
)
return
-
EIO
;
...
...
@@ -792,6 +797,9 @@ static void __exit bfusb_exit(void)
module_init
(
bfusb_init
);
module_exit
(
bfusb_exit
);
module_param
(
ignore
,
bool
,
0644
);
MODULE_PARM_DESC
(
ignore
,
"Ignore devices from the matching table"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"BlueFRITZ! USB driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
...
...
drivers/bluetooth/hci_bcsp.c
View file @
1cdd77fe
...
...
@@ -265,7 +265,7 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
/* This is a rewrite of pkt_avail in ABCSP */
static
struct
sk_buff
*
bcsp_dequeue
(
struct
hci_uart
*
hu
)
{
struct
bcsp_struct
*
bcsp
=
(
struct
bcsp_struct
*
)
hu
->
priv
;
struct
bcsp_struct
*
bcsp
=
hu
->
priv
;
unsigned
long
flags
;
struct
sk_buff
*
skb
;
...
...
@@ -629,7 +629,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
static
void
bcsp_timed_event
(
unsigned
long
arg
)
{
struct
hci_uart
*
hu
=
(
struct
hci_uart
*
)
arg
;
struct
bcsp_struct
*
bcsp
=
(
struct
bcsp_struct
*
)
hu
->
priv
;
struct
bcsp_struct
*
bcsp
=
hu
->
priv
;
struct
sk_buff
*
skb
;
unsigned
long
flags
;
...
...
drivers/bluetooth/hci_ldisc.c
View file @
1cdd77fe
...
...
@@ -51,6 +51,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include "hci_uart.h"
#ifndef CONFIG_BT_HCIUART_DEBUG
...
...
@@ -60,6 +61,8 @@
#define BT_DMP( A... )
#endif
static
int
reset
=
0
;
static
struct
hci_uart_proto
*
hup
[
HCI_UART_MAX_PROTO
];
int
hci_uart_register_proto
(
struct
hci_uart_proto
*
p
)
...
...
@@ -412,7 +415,10 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev
->
destruct
=
hci_uart_destruct
;
hdev
->
owner
=
THIS_MODULE
;
if
(
reset
)
set_bit
(
HCI_QUIRK_RESET_ON_INIT
,
&
hdev
->
quirks
);
if
(
hci_register_dev
(
hdev
)
<
0
)
{
BT_ERR
(
"Can't register HCI device"
);
hci_free_dev
(
hdev
);
...
...
@@ -577,7 +583,10 @@ static void __exit hci_uart_exit(void)
module_init
(
hci_uart_init
);
module_exit
(
hci_uart_exit
);
MODULE_AUTHOR
(
"Maxim Krasnyansky <maxk@qualcomm.com>"
);
module_param
(
reset
,
bool
,
0644
);
MODULE_PARM_DESC
(
reset
,
"Send HCI reset command on initialization"
);
MODULE_AUTHOR
(
"Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth HCI UART driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
drivers/bluetooth/hci_usb.c
View file @
1cdd77fe
...
...
@@ -66,6 +66,9 @@
#define URB_ZERO_PACKET 0
#endif
static
int
ignore
=
0
;
static
int
reset
=
0
;
#ifdef CONFIG_BT_HCIUSB_SCO
static
int
isoc
=
2
;
#endif
...
...
@@ -827,7 +830,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
id
=
match
;
}
if
(
id
->
driver_info
&
HCI_IGNORE
)
if
(
i
gnore
||
i
d
->
driver_info
&
HCI_IGNORE
)
return
-
ENODEV
;
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
>
0
)
...
...
@@ -963,7 +966,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
hdev
->
owner
=
THIS_MODULE
;
if
(
id
->
driver_info
&
HCI_RESET
)
if
(
reset
||
id
->
driver_info
&
HCI_RESET
)
set_bit
(
HCI_QUIRK_RESET_ON_INIT
,
&
hdev
->
quirks
);
if
(
hci_register_dev
(
hdev
)
<
0
)
{
...
...
@@ -1036,6 +1039,12 @@ static void __exit hci_usb_exit(void)
module_init
(
hci_usb_init
);
module_exit
(
hci_usb_exit
);
module_param
(
ignore
,
bool
,
0644
);
MODULE_PARM_DESC
(
ignore
,
"Ignore devices from the matching table"
);
module_param
(
reset
,
bool
,
0644
);
MODULE_PARM_DESC
(
reset
,
"Send HCI reset command on initialization"
);
#ifdef CONFIG_BT_HCIUSB_SCO
module_param
(
isoc
,
int
,
0644
);
MODULE_PARM_DESC
(
isoc
,
"Set isochronous transfers for SCO over HCI support"
);
...
...
include/net/bluetooth/hci_core.h
View file @
1cdd77fe
...
...
@@ -277,7 +277,6 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
return
NULL
;
}
void
hci_acl_connect
(
struct
hci_conn
*
conn
);
void
hci_acl_disconn
(
struct
hci_conn
*
conn
,
__u8
reason
);
void
hci_add_sco
(
struct
hci_conn
*
conn
,
__u16
handle
);
...
...
@@ -589,6 +588,5 @@ struct hci_sec_filter {
#define hci_req_unlock(d) up(&d->req_lock)
void
hci_req_complete
(
struct
hci_dev
*
hdev
,
int
result
);
void
hci_req_cancel
(
struct
hci_dev
*
hdev
,
int
err
);
#endif
/* __HCI_CORE_H */
include/net/bluetooth/l2cap.h
View file @
1cdd77fe
...
...
@@ -38,17 +38,19 @@ struct sockaddr_l2 {
bdaddr_t
l2_bdaddr
;
};
/*
S
ocket options */
/*
L2CAP s
ocket options */
#define L2CAP_OPTIONS 0x01
struct
l2cap_options
{
__u16
omtu
;
__u16
imtu
;
__u16
flush_to
;
__u8
mode
;
};
#define L2CAP_CONNINFO
0x02
#define L2CAP_CONNINFO
0x02
struct
l2cap_conninfo
{
__u16
hci_handle
;
__u8
dev_class
[
3
];
};
#define L2CAP_LM 0x03
...
...
@@ -59,20 +61,6 @@ struct l2cap_conninfo {
#define L2CAP_LM_RELIABLE 0x0010
#define L2CAP_LM_SECURE 0x0020
#define L2CAP_QOS 0x04
struct
l2cap_qos
{
__u16
service_type
;
__u32
token_rate
;
__u32
token_bucket_size
;
__u32
peak_bandwidth
;
__u32
latency
;
__u32
delay_variation
;
};
#define L2CAP_SERV_NO_TRAFFIC 0x00
#define L2CAP_SERV_BEST_EFFORT 0x01
#define L2CAP_SERV_GUARANTEED 0x02
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
#define L2CAP_CONN_REQ 0x02
...
...
@@ -154,6 +142,7 @@ struct l2cap_conf_opt {
#define L2CAP_CONF_MTU 0x01
#define L2CAP_CONF_FLUSH_TO 0x02
#define L2CAP_CONF_QOS 0x03
#define L2CAP_CONF_RFC 0x04
#define L2CAP_CONF_MAX_SIZE 22
...
...
@@ -198,11 +187,11 @@ struct l2cap_conn {
bdaddr_t
*
dst
;
bdaddr_t
*
src
;
unsigned
int
mtu
;
spinlock_t
lock
;
struct
sk_buff
*
rx_skb
;
__u32
rx_len
;
__u8
rx_ident
;
...
...
@@ -222,7 +211,7 @@ struct l2cap_pinfo {
__u16
imtu
;
__u16
omtu
;
__u16
flush_to
;
__u32
link_mode
;
__u8
conf_state
;
...
...
include/net/bluetooth/rfcomm.h
View file @
1cdd77fe
...
...
@@ -181,6 +181,8 @@ struct rfcomm_dlc {
u8
v24_sig
;
u8
mscex
;
u32
link_mode
;
uint
mtu
;
uint
cfc
;
uint
rx_credits
;
...
...
@@ -216,22 +218,6 @@ struct rfcomm_dlc {
#define RFCOMM_CFC_DISABLED 0
#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
extern
struct
task_struct
*
rfcomm_thread
;
extern
unsigned
long
rfcomm_event
;
static
inline
void
rfcomm_schedule
(
uint
event
)
{
if
(
!
rfcomm_thread
)
return
;
//set_bit(event, &rfcomm_event);
set_bit
(
RFCOMM_SCHED_WAKEUP
,
&
rfcomm_event
);
wake_up_process
(
rfcomm_thread
);
}
extern
struct
semaphore
rfcomm_sem
;
#define rfcomm_lock() down(&rfcomm_sem);
#define rfcomm_unlock() up(&rfcomm_sem);
/* ---- RFCOMM DLCs (channels) ---- */
struct
rfcomm_dlc
*
rfcomm_dlc_alloc
(
int
prio
);
void
rfcomm_dlc_free
(
struct
rfcomm_dlc
*
d
);
...
...
@@ -271,11 +257,6 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
}
/* ---- RFCOMM sessions ---- */
struct
rfcomm_session
*
rfcomm_session_add
(
struct
socket
*
sock
,
int
state
);
struct
rfcomm_session
*
rfcomm_session_get
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
);
struct
rfcomm_session
*
rfcomm_session_create
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
int
*
err
);
void
rfcomm_session_del
(
struct
rfcomm_session
*
s
);
void
rfcomm_session_close
(
struct
rfcomm_session
*
s
,
int
err
);
void
rfcomm_session_getaddr
(
struct
rfcomm_session
*
s
,
bdaddr_t
*
src
,
bdaddr_t
*
dst
);
static
inline
void
rfcomm_session_hold
(
struct
rfcomm_session
*
s
)
...
...
@@ -283,27 +264,36 @@ static inline void rfcomm_session_hold(struct rfcomm_session *s)
atomic_inc
(
&
s
->
refcnt
);
}
static
inline
void
rfcomm_session_put
(
struct
rfcomm_session
*
s
)
{
if
(
atomic_dec_and_test
(
&
s
->
refcnt
))
rfcomm_session_del
(
s
);
}
/* ---- RFCOMM chechsum ---- */
extern
u8
rfcomm_crc_table
[];
/* ---- RFCOMM sockets ---- */
struct
sockaddr_rc
{
sa_family_t
rc_family
;
bdaddr_t
rc_bdaddr
;
u8
rc_channel
;
sa_family_t
rc_family
;
bdaddr_t
rc_bdaddr
;
u8
rc_channel
;
};
#define RFCOMM_CONNINFO 0x02
struct
rfcomm_conninfo
{
__u16
hci_handle
;
__u8
dev_class
[
3
];
};
#define RFCOMM_LM 0x03
#define RFCOMM_LM_MASTER 0x0001
#define RFCOMM_LM_AUTH 0x0002
#define RFCOMM_LM_ENCRYPT 0x0004
#define RFCOMM_LM_TRUSTED 0x0008
#define RFCOMM_LM_RELIABLE 0x0010
#define RFCOMM_LM_SECURE 0x0020
#define rfcomm_pi(sk) ((struct rfcomm_pinfo *)sk->sk_protinfo)
struct
rfcomm_pinfo
{
struct
rfcomm_dlc
*
dlc
;
u8
channel
;
u32
link_mode
;
};
int
rfcomm_init_sockets
(
void
);
...
...
include/net/bluetooth/sco.h
View file @
1cdd77fe
...
...
@@ -39,15 +39,16 @@ struct sockaddr_sco {
bdaddr_t
sco_bdaddr
;
};
/*
set/get sockopt define
s */
#define SCO_OPTIONS
0x01
/*
SCO socket option
s */
#define SCO_OPTIONS
0x01
struct
sco_options
{
__u16
mtu
;
};
#define SCO_CONNINFO
0x02
#define SCO_CONNINFO
0x02
struct
sco_conninfo
{
__u16
hci_handle
;
__u8
dev_class
[
3
];
};
/* ---- SCO connections ---- */
...
...
net/bluetooth/cmtp/capi.c
View file @
1cdd77fe
...
...
@@ -139,6 +139,19 @@ static int cmtp_msgnum_get(struct cmtp_session *session)
return
session
->
msgnum
;
}
static
void
cmtp_send_capimsg
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
)
{
struct
cmtp_scb
*
scb
=
(
void
*
)
skb
->
cb
;
BT_DBG
(
"session %p skb %p len %d"
,
session
,
skb
,
skb
->
len
);
scb
->
id
=
-
1
;
scb
->
data
=
(
CAPIMSG_COMMAND
(
skb
->
data
)
==
CAPI_DATA_B3
);
skb_queue_tail
(
&
session
->
transmit
,
skb
);
cmtp_schedule
(
session
);
}
static
void
cmtp_send_interopmsg
(
struct
cmtp_session
*
session
,
__u8
subcmd
,
__u16
appl
,
__u16
msgnum
,
...
...
@@ -337,21 +350,6 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
capi_ctr_handle_message
(
ctrl
,
appl
,
skb
);
}
void
cmtp_send_capimsg
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
)
{
struct
cmtp_scb
*
scb
=
(
void
*
)
skb
->
cb
;
BT_DBG
(
"session %p skb %p len %d"
,
session
,
skb
,
skb
->
len
);
scb
->
id
=
-
1
;
scb
->
data
=
(
CAPIMSG_COMMAND
(
skb
->
data
)
==
CAPI_DATA_B3
);
skb_queue_tail
(
&
session
->
transmit
,
skb
);
cmtp_schedule
(
session
);
}
static
int
cmtp_load_firmware
(
struct
capi_ctr
*
ctrl
,
capiloaddata
*
data
)
{
BT_DBG
(
"ctrl %p data %p"
,
ctrl
,
data
);
...
...
net/bluetooth/cmtp/cmtp.h
View file @
1cdd77fe
...
...
@@ -120,7 +120,6 @@ int cmtp_attach_device(struct cmtp_session *session);
void
cmtp_detach_device
(
struct
cmtp_session
*
session
);
void
cmtp_recv_capimsg
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
);
void
cmtp_send_capimsg
(
struct
cmtp_session
*
session
,
struct
sk_buff
*
skb
);
static
inline
void
cmtp_schedule
(
struct
cmtp_session
*
session
)
{
...
...
net/bluetooth/hci_conn.c
View file @
1cdd77fe
...
...
@@ -53,7 +53,7 @@
#define BT_DBG(D...)
#endif
void
hci_acl_connect
(
struct
hci_conn
*
conn
)
static
void
hci_acl_connect
(
struct
hci_conn
*
conn
)
{
struct
hci_dev
*
hdev
=
conn
->
hdev
;
struct
inquiry_entry
*
ie
;
...
...
net/bluetooth/hci_core.c
View file @
1cdd77fe
...
...
@@ -59,7 +59,7 @@ 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
);
rwlock_t
hci_task_lock
=
RW_LOCK_UNLOCKED
;
static
rwlock_t
hci_task_lock
=
RW_LOCK_UNLOCKED
;
/* HCI device list */
LIST_HEAD
(
hci_dev_list
);
...
...
@@ -106,7 +106,7 @@ void hci_req_complete(struct hci_dev *hdev, int result)
}
}
void
hci_req_cancel
(
struct
hci_dev
*
hdev
,
int
err
)
static
void
hci_req_cancel
(
struct
hci_dev
*
hdev
,
int
err
)
{
BT_DBG
(
"%s err 0x%2.2x"
,
hdev
->
name
,
err
);
...
...
net/bluetooth/hci_sock.c
View file @
1cdd77fe
...
...
@@ -447,7 +447,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto
done
;
}
int
hci_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
len
)
static
int
hci_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
len
)
{
struct
hci_ufilter
uf
=
{
.
opcode
=
0
};
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -514,7 +514,7 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user
return
err
;
}
int
hci_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
static
int
hci_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
hci_ufilter
uf
;
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -567,7 +567,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user
return
0
;
}
struct
proto_ops
hci_sock_ops
=
{
st
atic
st
ruct
proto_ops
hci_sock_ops
=
{
.
family
=
PF_BLUETOOTH
,
.
owner
=
THIS_MODULE
,
.
release
=
hci_sock_release
,
...
...
@@ -647,13 +647,13 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
return
NOTIFY_DONE
;
}
struct
net_proto_family
hci_sock_family_ops
=
{
st
atic
st
ruct
net_proto_family
hci_sock_family_ops
=
{
.
family
=
PF_BLUETOOTH
,
.
owner
=
THIS_MODULE
,
.
create
=
hci_sock_create
,
};
struct
notifier_block
hci_sock_nblock
=
{
st
atic
st
ruct
notifier_block
hci_sock_nblock
=
{
.
notifier_call
=
hci_sock_dev_event
};
...
...
net/bluetooth/hidp/core.c
View file @
1cdd77fe
...
...
@@ -50,7 +50,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "1.
0
"
#define VERSION "1.
1
"
static
DECLARE_RWSEM
(
hidp_session_sem
);
static
LIST_HEAD
(
hidp_session_list
);
...
...
@@ -130,7 +130,7 @@ static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned i
struct
sk_buff
*
skb
;
unsigned
char
newleds
;
BT_DBG
(
"
session %p hid %p data %p size %d"
,
session
,
device
,
data
,
siz
e
);
BT_DBG
(
"
input %p type %d code %d value %d"
,
dev
,
type
,
code
,
valu
e
);
if
(
type
!=
EV_LED
)
return
-
1
;
...
...
@@ -151,7 +151,7 @@ static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned i
return
-
ENOMEM
;
}
*
skb_put
(
skb
,
1
)
=
0xa2
;
*
skb_put
(
skb
,
1
)
=
HIDP_TRANS_DATA
|
HIDP_DATA_RTYPE_OUPUT
;
*
skb_put
(
skb
,
1
)
=
0x01
;
*
skb_put
(
skb
,
1
)
=
newleds
;
...
...
@@ -232,36 +232,171 @@ static inline void hidp_del_timer(struct hidp_session *session)
del_timer
(
&
session
->
timer
);
}
static
inline
void
hidp_send_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
)
static
int
__hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
struct
sk_buff
*
skb
;
BT_DBG
(
"session %p
"
,
session
);
BT_DBG
(
"session %p
data %p size %d"
,
session
,
data
,
size
);
if
(
!
(
skb
=
alloc_skb
(
1
,
GFP_ATOMIC
)))
{
BT_ERR
(
"Can't allocate memory for
messag
e"
);
return
;
if
(
!
(
skb
=
alloc_skb
(
size
+
1
,
GFP_ATOMIC
)))
{
BT_ERR
(
"Can't allocate memory for
new fram
e"
);
return
-
ENOMEM
;
}
*
skb_put
(
skb
,
1
)
=
hdr
;
if
(
data
&&
size
>
0
)
memcpy
(
skb_put
(
skb
,
size
),
data
,
size
);
skb_queue_tail
(
&
session
->
ctrl_transmit
,
skb
);
return
0
;
}
static
int
inline
hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
int
err
;
err
=
__hidp_send_ctrl_message
(
session
,
hdr
,
data
,
size
);
hidp_schedule
(
session
);
return
err
;
}
static
inline
void
hidp_process_handshake
(
struct
hidp_session
*
session
,
unsigned
char
param
)
{
BT_DBG
(
"session %p param 0x%02x"
,
session
,
param
);
switch
(
param
)
{
case
HIDP_HSHK_SUCCESSFUL
:
/* FIXME: Call into SET_ GET_ handlers here */
break
;
case
HIDP_HSHK_NOT_READY
:
case
HIDP_HSHK_ERR_INVALID_REPORT_ID
:
case
HIDP_HSHK_ERR_UNSUPPORTED_REQUEST
:
case
HIDP_HSHK_ERR_INVALID_PARAMETER
:
/* FIXME: Call into SET_ GET_ handlers here */
break
;
case
HIDP_HSHK_ERR_UNKNOWN
:
break
;
case
HIDP_HSHK_ERR_FATAL
:
/* Device requests a reboot, as this is the only way this error
* can be recovered. */
__hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HID_CONTROL
|
HIDP_CTRL_SOFT_RESET
,
NULL
,
0
);
break
;
default:
__hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HANDSHAKE
|
HIDP_HSHK_ERR_INVALID_PARAMETER
,
NULL
,
0
);
break
;
}
}
static
inline
void
hidp_process_hid_control
(
struct
hidp_session
*
session
,
unsigned
char
param
)
{
BT_DBG
(
"session %p param 0x%02x"
,
session
,
param
);
switch
(
param
)
{
case
HIDP_CTRL_NOP
:
break
;
case
HIDP_CTRL_VIRTUAL_CABLE_UNPLUG
:
/* Flush the transmit queues */
skb_queue_purge
(
&
session
->
ctrl_transmit
);
skb_queue_purge
(
&
session
->
intr_transmit
);
/* Kill session thread */
atomic_inc
(
&
session
->
terminate
);
break
;
case
HIDP_CTRL_HARD_RESET
:
case
HIDP_CTRL_SOFT_RESET
:
case
HIDP_CTRL_SUSPEND
:
case
HIDP_CTRL_EXIT_SUSPEND
:
/* FIXME: We have to parse these and return no error */
break
;
default:
__hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HANDSHAKE
|
HIDP_HSHK_ERR_INVALID_PARAMETER
,
NULL
,
0
);
break
;
}
}
static
inline
int
hidp_recv_frame
(
struct
hidp_session
*
session
,
struct
sk_buff
*
skb
)
static
inline
void
hidp_process_data
(
struct
hidp_session
*
session
,
struct
sk_buff
*
skb
,
unsigned
char
param
)
{
__u8
hdr
;
BT_DBG
(
"session %p skb %p len %d param 0x%02x"
,
session
,
skb
,
skb
->
len
,
param
);
switch
(
param
)
{
case
HIDP_DATA_RTYPE_INPUT
:
hidp_set_timer
(
session
);
if
(
session
->
input
)
hidp_input_report
(
session
,
skb
);
break
;
case
HIDP_DATA_RTYPE_OTHER
:
case
HIDP_DATA_RTYPE_OUPUT
:
case
HIDP_DATA_RTYPE_FEATURE
:
break
;
default:
__hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HANDSHAKE
|
HIDP_HSHK_ERR_INVALID_PARAMETER
,
NULL
,
0
);
}
}
static
inline
void
hidp_recv_ctrl_frame
(
struct
hidp_session
*
session
,
struct
sk_buff
*
skb
)
{
unsigned
char
hdr
,
type
,
param
;
BT_DBG
(
"session %p skb %p len %d"
,
session
,
skb
,
skb
->
len
);
hdr
=
skb
->
data
[
0
];
skb_pull
(
skb
,
1
);
if
(
hdr
==
0xa1
)
{
hidp_set_timer
(
session
);
type
=
hdr
&
HIDP_HEADER_TRANS_MASK
;
param
=
hdr
&
HIDP_HEADER_PARAM_MASK
;
switch
(
type
)
{
case
HIDP_TRANS_HANDSHAKE
:
hidp_process_handshake
(
session
,
param
);
break
;
case
HIDP_TRANS_HID_CONTROL
:
hidp_process_hid_control
(
session
,
param
);
break
;
case
HIDP_TRANS_DATA
:
hidp_process_data
(
session
,
skb
,
param
);
break
;
default:
__hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HANDSHAKE
|
HIDP_HSHK_ERR_UNSUPPORTED_REQUEST
,
NULL
,
0
);
break
;
}
kfree_skb
(
skb
);
}
static
inline
void
hidp_recv_intr_frame
(
struct
hidp_session
*
session
,
struct
sk_buff
*
skb
)
{
unsigned
char
hdr
;
BT_DBG
(
"session %p skb %p len %d"
,
session
,
skb
,
skb
->
len
);
hdr
=
skb
->
data
[
0
];
skb_pull
(
skb
,
1
);
if
(
hdr
==
(
HIDP_TRANS_DATA
|
HIDP_DATA_RTYPE_INPUT
))
{
hidp_set_timer
(
session
);
if
(
session
->
input
)
hidp_input_report
(
session
,
skb
);
}
else
{
...
...
@@ -269,7 +404,6 @@ static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *
}
kfree_skb
(
skb
);
return
0
;
}
static
int
hidp_send_frame
(
struct
socket
*
sock
,
unsigned
char
*
data
,
int
len
)
...
...
@@ -350,12 +484,12 @@ static int hidp_session(void *arg)
while
((
skb
=
skb_dequeue
(
&
ctrl_sk
->
sk_receive_queue
)))
{
skb_orphan
(
skb
);
hidp_recv_frame
(
session
,
skb
);
hidp_recv_
ctrl_
frame
(
session
,
skb
);
}
while
((
skb
=
skb_dequeue
(
&
intr_sk
->
sk_receive_queue
)))
{
skb_orphan
(
skb
);
hidp_recv_frame
(
session
,
skb
);
hidp_recv_
intr_
frame
(
session
,
skb
);
}
hidp_process_transmit
(
session
);
...
...
@@ -514,7 +648,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
goto
unlink
;
if
(
session
->
input
)
{
hidp_send_message
(
session
,
0x70
);
hidp_send_ctrl_message
(
session
,
HIDP_TRANS_SET_PROTOCOL
|
HIDP_PROTO_BOOT
,
NULL
,
0
);
session
->
flags
|=
(
1
<<
HIDP_BOOT_PROTOCOL_MODE
);
session
->
leds
=
0xff
;
...
...
@@ -554,7 +689,8 @@ int hidp_del_connection(struct hidp_conndel_req *req)
session
=
__hidp_get_session
(
&
req
->
bdaddr
);
if
(
session
)
{
if
(
req
->
flags
&
(
1
<<
HIDP_VIRTUAL_CABLE_UNPLUG
))
{
hidp_send_message
(
session
,
0x15
);
hidp_send_ctrl_message
(
session
,
HIDP_TRANS_HID_CONTROL
|
HIDP_CTRL_VIRTUAL_CABLE_UNPLUG
,
NULL
,
0
);
}
else
{
/* Flush the transmit queues */
skb_queue_purge
(
&
session
->
ctrl_transmit
);
...
...
net/bluetooth/hidp/hidp.h
View file @
1cdd77fe
...
...
@@ -26,6 +26,51 @@
#include <linux/types.h>
#include <net/bluetooth/bluetooth.h>
/* HIDP header masks */
#define HIDP_HEADER_TRANS_MASK 0xf0
#define HIDP_HEADER_PARAM_MASK 0x0f
/* HIDP transaction types */
#define HIDP_TRANS_HANDSHAKE 0x00
#define HIDP_TRANS_HID_CONTROL 0x10
#define HIDP_TRANS_GET_REPORT 0x40
#define HIDP_TRANS_SET_REPORT 0x50
#define HIDP_TRANS_GET_PROTOCOL 0x60
#define HIDP_TRANS_SET_PROTOCOL 0x70
#define HIDP_TRANS_GET_IDLE 0x80
#define HIDP_TRANS_SET_IDLE 0x90
#define HIDP_TRANS_DATA 0xa0
#define HIDP_TRANS_DATC 0xb0
/* HIDP handshake results */
#define HIDP_HSHK_SUCCESSFUL 0x00
#define HIDP_HSHK_NOT_READY 0x01
#define HIDP_HSHK_ERR_INVALID_REPORT_ID 0x02
#define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST 0x03
#define HIDP_HSHK_ERR_INVALID_PARAMETER 0x04
#define HIDP_HSHK_ERR_UNKNOWN 0x0e
#define HIDP_HSHK_ERR_FATAL 0x0f
/* HIDP control operation parameters */
#define HIDP_CTRL_NOP 0x00
#define HIDP_CTRL_HARD_RESET 0x01
#define HIDP_CTRL_SOFT_RESET 0x02
#define HIDP_CTRL_SUSPEND 0x03
#define HIDP_CTRL_EXIT_SUSPEND 0x04
#define HIDP_CTRL_VIRTUAL_CABLE_UNPLUG 0x05
/* HIDP data transaction headers */
#define HIDP_DATA_RTYPE_MASK 0x03
#define HIDP_DATA_RSRVD_MASK 0x0c
#define HIDP_DATA_RTYPE_OTHER 0x00
#define HIDP_DATA_RTYPE_INPUT 0x01
#define HIDP_DATA_RTYPE_OUPUT 0x02
#define HIDP_DATA_RTYPE_FEATURE 0x03
/* HIDP protocol header parameters */
#define HIDP_PROTO_BOOT 0x00
#define HIDP_PROTO_REPORT 0x01
/* HIDP ioctl defines */
#define HIDPCONNADD _IOW('H', 200, int)
#define HIDPCONNDEL _IOW('H', 201, int)
...
...
net/bluetooth/l2cap.c
View file @
1cdd77fe
...
...
@@ -57,11 +57,11 @@
#define BT_DBG(D...)
#endif
#define VERSION "2.
6
"
#define VERSION "2.
7
"
static
struct
proto_ops
l2cap_sock_ops
;
struct
bt_sock_list
l2cap_sk_list
=
{
st
atic
st
ruct
bt_sock_list
l2cap_sk_list
=
{
.
lock
=
RW_LOCK_UNLOCKED
};
...
...
@@ -798,7 +798,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
switch
(
optname
)
{
case
L2CAP_OPTIONS
:
len
=
min_t
(
unsigned
int
,
sizeof
(
opts
),
optlen
);
if
(
copy_from_user
((
char
*
)
&
opts
,
optval
,
len
))
{
if
(
copy_from_user
((
char
*
)
&
opts
,
optval
,
len
))
{
err
=
-
EFAULT
;
break
;
}
...
...
@@ -807,7 +807,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
break
;
case
L2CAP_LM
:
if
(
get_user
(
opt
,
(
u32
__user
*
)
optval
))
{
if
(
get_user
(
opt
,
(
u32
__user
*
)
optval
))
{
err
=
-
EFAULT
;
break
;
}
...
...
@@ -829,7 +829,9 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
struct
sock
*
sk
=
sock
->
sk
;
struct
l2cap_options
opts
;
struct
l2cap_conninfo
cinfo
;
int
len
,
err
=
0
;
int
len
,
err
=
0
;
BT_DBG
(
"sk %p"
,
sk
);
if
(
get_user
(
len
,
optlen
))
return
-
EFAULT
;
...
...
@@ -841,15 +843,16 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
opts
.
imtu
=
l2cap_pi
(
sk
)
->
imtu
;
opts
.
omtu
=
l2cap_pi
(
sk
)
->
omtu
;
opts
.
flush_to
=
l2cap_pi
(
sk
)
->
flush_to
;
opts
.
mode
=
0x00
;
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
opts
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
opts
,
len
))
if
(
copy_to_user
(
optval
,
(
char
*
)
&
opts
,
len
))
err
=
-
EFAULT
;
break
;
case
L2CAP_LM
:
if
(
put_user
(
l2cap_pi
(
sk
)
->
link_mode
,
(
u32
__user
*
)
optval
))
if
(
put_user
(
l2cap_pi
(
sk
)
->
link_mode
,
(
u32
__user
*
)
optval
))
err
=
-
EFAULT
;
break
;
...
...
@@ -860,9 +863,10 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
}
cinfo
.
hci_handle
=
l2cap_pi
(
sk
)
->
conn
->
hcon
->
handle
;
memcpy
(
cinfo
.
dev_class
,
l2cap_pi
(
sk
)
->
conn
->
hcon
->
dev_class
,
3
);
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
cinfo
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
cinfo
,
len
))
if
(
copy_to_user
(
optval
,
(
char
*
)
&
cinfo
,
len
))
err
=
-
EFAULT
;
break
;
...
...
net/bluetooth/rfcomm/core.c
View file @
1cdd77fe
...
...
@@ -50,7 +50,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#define VERSION "1.
3
"
#define VERSION "1.
4
"
#ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG
...
...
@@ -61,8 +61,12 @@
struct
proc_dir_entry
*
proc_bt_rfcomm
;
#endif
struct
task_struct
*
rfcomm_thread
;
DECLARE_MUTEX
(
rfcomm_sem
);
static
struct
task_struct
*
rfcomm_thread
;
static
DECLARE_MUTEX
(
rfcomm_sem
);
#define rfcomm_lock() down(&rfcomm_sem);
#define rfcomm_unlock() up(&rfcomm_sem);
unsigned
long
rfcomm_event
;
static
LIST_HEAD
(
session_list
);
...
...
@@ -81,6 +85,10 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
static
void
rfcomm_process_connect
(
struct
rfcomm_session
*
s
);
static
struct
rfcomm_session
*
rfcomm_session_create
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
int
*
err
);
static
struct
rfcomm_session
*
rfcomm_session_get
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
);
static
void
rfcomm_session_del
(
struct
rfcomm_session
*
s
);
/* ---- RFCOMM frame parsing macros ---- */
#define __get_dlci(b) ((b & 0xfc) >> 2)
#define __get_channel(b) ((b & 0xf8) >> 3)
...
...
@@ -111,6 +119,21 @@ static void rfcomm_process_connect(struct rfcomm_session *s);
#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
static
inline
void
rfcomm_schedule
(
uint
event
)
{
if
(
!
rfcomm_thread
)
return
;
//set_bit(event, &rfcomm_event);
set_bit
(
RFCOMM_SCHED_WAKEUP
,
&
rfcomm_event
);
wake_up_process
(
rfcomm_thread
);
}
static
inline
void
rfcomm_session_put
(
struct
rfcomm_session
*
s
)
{
if
(
atomic_dec_and_test
(
&
s
->
refcnt
))
rfcomm_session_del
(
s
);
}
/* ---- RFCOMM FCS computation ---- */
/* CRC on 2 bytes */
...
...
@@ -458,7 +481,7 @@ int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
}
/* ---- RFCOMM sessions ---- */
struct
rfcomm_session
*
rfcomm_session_add
(
struct
socket
*
sock
,
int
state
)
st
atic
st
ruct
rfcomm_session
*
rfcomm_session_add
(
struct
socket
*
sock
,
int
state
)
{
struct
rfcomm_session
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
...
...
@@ -487,7 +510,7 @@ struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
return
s
;
}
void
rfcomm_session_del
(
struct
rfcomm_session
*
s
)
static
void
rfcomm_session_del
(
struct
rfcomm_session
*
s
)
{
int
state
=
s
->
state
;
...
...
@@ -505,7 +528,7 @@ void rfcomm_session_del(struct rfcomm_session *s)
module_put
(
THIS_MODULE
);
}
struct
rfcomm_session
*
rfcomm_session_get
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
)
st
atic
st
ruct
rfcomm_session
*
rfcomm_session_get
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
)
{
struct
rfcomm_session
*
s
;
struct
list_head
*
p
,
*
n
;
...
...
@@ -521,7 +544,7 @@ struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
return
NULL
;
}
void
rfcomm_session_close
(
struct
rfcomm_session
*
s
,
int
err
)
static
void
rfcomm_session_close
(
struct
rfcomm_session
*
s
,
int
err
)
{
struct
rfcomm_dlc
*
d
;
struct
list_head
*
p
,
*
n
;
...
...
@@ -542,7 +565,7 @@ void rfcomm_session_close(struct rfcomm_session *s, int err)
rfcomm_session_put
(
s
);
}
struct
rfcomm_session
*
rfcomm_session_create
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
int
*
err
)
st
atic
st
ruct
rfcomm_session
*
rfcomm_session_create
(
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
int
*
err
)
{
struct
rfcomm_session
*
s
=
NULL
;
struct
sockaddr_l2
addr
;
...
...
net/bluetooth/rfcomm/sock.c
View file @
1cdd77fe
...
...
@@ -51,6 +51,8 @@
#include <asm/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#ifndef CONFIG_BT_RFCOMM_DEBUG
...
...
@@ -261,10 +263,18 @@ static void rfcomm_sock_close(struct sock *sk)
static
void
rfcomm_sock_init
(
struct
sock
*
sk
,
struct
sock
*
parent
)
{
struct
rfcomm_pinfo
*
pi
=
rfcomm_pi
(
sk
);
BT_DBG
(
"sk %p"
,
sk
);
if
(
parent
)
if
(
parent
)
{
sk
->
sk_type
=
parent
->
sk_type
;
pi
->
link_mode
=
rfcomm_pi
(
parent
)
->
link_mode
;
}
else
{
pi
->
link_mode
=
0
;
}
pi
->
dlc
->
link_mode
=
pi
->
link_mode
;
}
static
struct
sock
*
rfcomm_sock_alloc
(
struct
socket
*
sock
,
int
proto
,
int
prio
)
...
...
@@ -393,7 +403,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
return
err
;
}
int
rfcomm_sock_listen
(
struct
socket
*
sock
,
int
backlog
)
static
int
rfcomm_sock_listen
(
struct
socket
*
sock
,
int
backlog
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
...
...
@@ -437,7 +447,7 @@ int rfcomm_sock_listen(struct socket *sock, int backlog)
return
err
;
}
int
rfcomm_sock_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
static
int
rfcomm_sock_accept
(
struct
socket
*
sock
,
struct
socket
*
newsock
,
int
flags
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
struct
sock
*
sk
=
sock
->
sk
,
*
nsk
;
...
...
@@ -671,12 +681,22 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
u32
opt
;
BT_DBG
(
"sk %p"
,
sk
);
lock_sock
(
sk
);
switch
(
optname
)
{
case
RFCOMM_LM
:
if
(
get_user
(
opt
,
(
u32
__user
*
)
optval
))
{
err
=
-
EFAULT
;
break
;
}
rfcomm_pi
(
sk
)
->
link_mode
=
opt
;
break
;
default:
err
=
-
ENOPROTOOPT
;
break
;
...
...
@@ -689,7 +709,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
static
int
rfcomm_sock_getsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
__user
*
optval
,
int
__user
*
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
len
,
err
=
0
;
struct
sock
*
l2cap_sk
;
struct
rfcomm_conninfo
cinfo
;
int
len
,
err
=
0
;
BT_DBG
(
"sk %p"
,
sk
);
...
...
@@ -699,10 +721,32 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
lock_sock
(
sk
);
switch
(
optname
)
{
case
RFCOMM_LM
:
if
(
put_user
(
rfcomm_pi
(
sk
)
->
link_mode
,
(
u32
__user
*
)
optval
))
err
=
-
EFAULT
;
break
;
case
RFCOMM_CONNINFO
:
if
(
sk
->
sk_state
!=
BT_CONNECTED
)
{
err
=
-
ENOTCONN
;
break
;
}
l2cap_sk
=
rfcomm_pi
(
sk
)
->
dlc
->
session
->
sock
->
sk
;
cinfo
.
hci_handle
=
l2cap_pi
(
l2cap_sk
)
->
conn
->
hcon
->
handle
;
memcpy
(
cinfo
.
dev_class
,
l2cap_pi
(
l2cap_sk
)
->
conn
->
hcon
->
dev_class
,
3
);
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
cinfo
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
cinfo
,
len
))
err
=
-
EFAULT
;
break
;
default:
err
=
-
ENOPROTOOPT
;
break
;
}
;
}
release_sock
(
sk
);
return
err
;
...
...
net/bluetooth/sco.c
View file @
1cdd77fe
...
...
@@ -56,7 +56,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "0.
3
"
#define VERSION "0.
4
"
static
struct
proto_ops
sco_sock_ops
;
...
...
@@ -705,6 +705,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
}
cinfo
.
hci_handle
=
sco_pi
(
sk
)
->
conn
->
hcon
->
handle
;
memcpy
(
cinfo
.
dev_class
,
sco_pi
(
sk
)
->
conn
->
hcon
->
dev_class
,
3
);
len
=
min_t
(
unsigned
int
,
len
,
sizeof
(
cinfo
));
if
(
copy_to_user
(
optval
,
(
char
*
)
&
cinfo
,
len
))
...
...
@@ -1045,7 +1046,7 @@ static void __exit sco_exit(void)
module_init
(
sco_init
);
module_exit
(
sco_exit
);
MODULE_AUTHOR
(
"Maxim Krasnyansky <maxk@qualcomm.com>"
);
MODULE_AUTHOR
(
"Maxim Krasnyansky <maxk@qualcomm.com>
, Marcel Holtmann <marcel@holtmann.org>
"
);
MODULE_DESCRIPTION
(
"Bluetooth SCO ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
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