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
6e21ae5b
Commit
6e21ae5b
authored
Aug 23, 2003
by
Maksim Krasnyanskiy
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux.bkbits.net/linux-2.5
into qualcomm.com:/home/kernel/bt-2.5
parents
6cf73674
a17a125c
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
339 additions
and
156 deletions
+339
-156
CREDITS
CREDITS
+2
-1
MAINTAINERS
MAINTAINERS
+50
-2
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.c
+2
-1
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+1
-1
include/net/bluetooth/hci.h
include/net/bluetooth/hci.h
+2
-0
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap.h
+2
-0
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+9
-13
net/bluetooth/hci_core.c
net/bluetooth/hci_core.c
+6
-3
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+13
-0
net/bluetooth/hci_sock.c
net/bluetooth/hci_sock.c
+1
-1
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+49
-25
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+89
-13
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+41
-34
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+55
-56
net/bluetooth/sco.c
net/bluetooth/sco.c
+16
-5
net/bluetooth/syms.c
net/bluetooth/syms.c
+1
-1
No files found.
CREDITS
View file @
6e21ae5b
...
...
@@ -1387,7 +1387,8 @@ S: USA
N: Marcel Holtmann
E: marcel@holtmann.org
W: http://www.holtmann.org
D: Author of the Linux Bluetooth Subsystem PC Card drivers
D: Author and maintainer of the various Bluetooth HCI drivers
D: Various other Bluetooth related patches, cleanups and fixes
S: Germany
N: Rob W. W. Hooft
...
...
MAINTAINERS
View file @
6e21ae5b
...
...
@@ -328,18 +328,66 @@ M: axboe@suse.de
L: linux-kernel@vger.kernel.org
S: Maintained
BLUETOOTH SUBSYSTEM
(BlueZ)
BLUETOOTH SUBSYSTEM
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH SUBSYSTEM (PC Card Drivers)
BLUETOOTH RFCOMM LAYER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH BNEP LAYER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH HCI USB DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH HCI UART DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH HCI DTL1 DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BLUECARD DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BT3C DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BTUART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI VHCI DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BONDING DRIVER
P: Chad Tindel
M: ctindel@users.sourceforge.net
...
...
drivers/bluetooth/hci_usb.c
View file @
6e21ae5b
...
...
@@ -303,7 +303,8 @@ static int hci_usb_open(struct hci_dev *hdev)
hci_usb_bulk_rx_submit
(
husb
);
#ifdef CONFIG_BT_USB_SCO
hci_usb_isoc_rx_submit
(
husb
);
if
(
husb
->
isoc_iface
)
hci_usb_isoc_rx_submit
(
husb
);
#endif
}
else
{
clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
);
...
...
include/net/bluetooth/bluetooth.h
View file @
6e21ae5b
...
...
@@ -131,7 +131,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void
bt_sock_unlink
(
struct
bt_sock_list
*
l
,
struct
sock
*
s
);
int
bt_sock_recvmsg
(
struct
kiocb
*
iocb
,
struct
socket
*
sock
,
struct
msghdr
*
msg
,
int
len
,
int
flags
);
uint
bt_sock_poll
(
struct
file
*
file
,
struct
socket
*
sock
,
poll_table
*
wait
);
int
bt_sock_w
4_connect
(
struct
sock
*
sk
,
int
flags
);
int
bt_sock_w
ait_state
(
struct
sock
*
sk
,
int
state
,
unsigned
long
timeo
);
void
bt_accept_enqueue
(
struct
sock
*
parent
,
struct
sock
*
sk
);
struct
sock
*
bt_accept_dequeue
(
struct
sock
*
parent
,
struct
socket
*
newsock
);
...
...
include/net/bluetooth/hci.h
View file @
6e21ae5b
...
...
@@ -304,6 +304,8 @@ struct hci_cp_inquiry {
__u8
num_rsp
;
}
__attribute__
((
packed
));
#define OCF_INQUIRY_CANCEL 0x0002
#define OCF_LINK_KEY_REPLY 0x000B
#define OCF_LINK_KEY_NEG_REPLY 0x000C
struct
hci_cp_link_key_reply
{
...
...
include/net/bluetooth/l2cap.h
View file @
6e21ae5b
...
...
@@ -220,6 +220,7 @@ struct l2cap_pinfo {
__u32
link_mode
;
__u8
conf_state
;
__u8
conf_retry
;
__u16
conf_mtu
;
__u8
ident
;
...
...
@@ -234,6 +235,7 @@ struct l2cap_pinfo {
#define L2CAP_CONF_REQ_SENT 0x01
#define L2CAP_CONF_INPUT_DONE 0x02
#define L2CAP_CONF_OUTPUT_DONE 0x04
#define L2CAP_CONF_MAX_RETRIES 2
void
l2cap_load
(
void
);
...
...
net/bluetooth/af_bluetooth.c
View file @
6e21ae5b
...
...
@@ -27,7 +27,7 @@
*
* $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
*/
#define VERSION "2.
2
"
#define VERSION "2.
3
"
#include <linux/config.h>
#include <linux/module.h>
...
...
@@ -272,39 +272,35 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
return
mask
;
}
int
bt_sock_w
4_connect
(
struct
sock
*
sk
,
int
flags
)
int
bt_sock_w
ait_state
(
struct
sock
*
sk
,
int
state
,
unsigned
long
timeo
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
long
timeo
=
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
);
int
err
=
0
;
BT_DBG
(
"sk %p"
,
sk
);
add_wait_queue
(
sk
->
sk_sleep
,
&
wait
);
while
(
sk
->
sk_state
!=
BT_CONNECTED
)
{
while
(
sk
->
sk_state
!=
state
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
if
(
!
timeo
)
{
err
=
-
EAGAIN
;
break
;
}
if
(
signal_pending
(
current
))
{
err
=
sock_intr_errno
(
timeo
);
break
;
}
release_sock
(
sk
);
timeo
=
schedule_timeout
(
timeo
);
lock_sock
(
sk
);
err
=
0
;
if
(
sk
->
sk_state
==
BT_CONNECTED
)
break
;
if
(
sk
->
sk_err
)
{
err
=
sock_error
(
sk
);
break
;
}
if
(
signal_pending
(
current
))
{
err
=
sock_intr_errno
(
timeo
);
break
;
}
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
sk
->
sk_sleep
,
&
wait
);
...
...
net/bluetooth/hci_core.c
View file @
6e21ae5b
...
...
@@ -394,7 +394,7 @@ int hci_inquiry(unsigned long arg)
{
struct
hci_inquiry_req
ir
;
struct
hci_dev
*
hdev
;
int
err
=
0
,
do_inquiry
=
0
;
int
err
=
0
,
do_inquiry
=
0
,
max_rsp
;
long
timeo
;
__u8
*
buf
,
*
ptr
;
...
...
@@ -417,16 +417,19 @@ int hci_inquiry(unsigned long arg)
if
(
do_inquiry
&&
(
err
=
hci_request
(
hdev
,
hci_inq_req
,
(
unsigned
long
)
&
ir
,
timeo
))
<
0
)
goto
done
;
/* for unlimited number of responses we will use buffer with 255 entries */
max_rsp
=
(
ir
.
num_rsp
==
0
)
?
255
:
ir
.
num_rsp
;
/* cache_dump can't sleep. Therefore we allocate temp buffer and then
* copy it to the user space.
*/
if
(
!
(
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
ir
.
num
_rsp
,
GFP_KERNEL
)))
{
if
(
!
(
buf
=
kmalloc
(
sizeof
(
struct
inquiry_info
)
*
max
_rsp
,
GFP_KERNEL
)))
{
err
=
-
ENOMEM
;
goto
done
;
}
hci_dev_lock_bh
(
hdev
);
ir
.
num_rsp
=
inquiry_cache_dump
(
hdev
,
ir
.
num
_rsp
,
buf
);
ir
.
num_rsp
=
inquiry_cache_dump
(
hdev
,
max
_rsp
,
buf
);
hci_dev_unlock_bh
(
hdev
);
BT_DBG
(
"num_rsp %d"
,
ir
.
num_rsp
);
...
...
net/bluetooth/hci_event.c
View file @
6e21ae5b
...
...
@@ -62,9 +62,22 @@
/* Command Complete OGF LINK_CTL */
static
void
hci_cc_link_ctl
(
struct
hci_dev
*
hdev
,
__u16
ocf
,
struct
sk_buff
*
skb
)
{
__u8
status
;
BT_DBG
(
"%s ocf 0x%x"
,
hdev
->
name
,
ocf
);
switch
(
ocf
)
{
case
OCF_INQUIRY_CANCEL
:
status
=
*
((
__u8
*
)
skb
->
data
);
if
(
status
)
{
BT_DBG
(
"%s Inquiry cancel error: status 0x%x"
,
hdev
->
name
,
status
);
}
else
{
clear_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
);
hci_req_complete
(
hdev
,
status
);
}
break
;
default:
BT_DBG
(
"%s Command complete: ogf LINK_CTL ocf %x"
,
hdev
->
name
,
ocf
);
break
;
...
...
net/bluetooth/hci_sock.c
View file @
6e21ae5b
...
...
@@ -75,7 +75,7 @@ static struct hci_sec_filter hci_sec_filter = {
/* OGF_LINK_POLICY */
{
0x1200
,
0x0
,
0x0
,
0x0
},
/* OGF_HOST_CTL */
{
0x80100000
,
0x2a
,
0x0
,
0x0
},
{
0x80100000
,
0x2
02
a
,
0x0
,
0x0
},
/* OGF_INFO_PARAM */
{
0x22a
,
0x0
,
0x0
,
0x0
},
/* OGF_STATUS_PARAM */
...
...
net/bluetooth/l2cap.c
View file @
6e21ae5b
...
...
@@ -290,7 +290,7 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
struct
l2cap_disconn_req
req
;
sk
->
sk_state
=
BT_DISCONN
;
l2cap_sock_set_timer
(
sk
,
HZ
*
5
);
l2cap_sock_set_timer
(
sk
,
sk
->
sk_sndtimeo
);
req
.
dcid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
dcid
);
req
.
scid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
...
...
@@ -315,11 +315,9 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
static
void
l2cap_sock_close
(
struct
sock
*
sk
)
{
l2cap_sock_clear_timer
(
sk
);
lock_sock
(
sk
);
__l2cap_sock_close
(
sk
,
ECONNRESET
);
release_sock
(
sk
);
l2cap_sock_kill
(
sk
);
}
...
...
@@ -531,8 +529,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
goto
done
;
wait:
err
=
bt_sock_w
4_connect
(
sk
,
flags
);
err
=
bt_sock_w
ait_state
(
sk
,
BT_CONNECTED
,
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
));
done:
release_sock
(
sk
);
return
err
;
...
...
@@ -832,32 +830,39 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
static
int
l2cap_sock_shutdown
(
struct
socket
*
sock
,
int
how
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
l2cap_sock_clear_timer
(
sk
);
lock_sock
(
sk
);
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
__l2cap_sock_close
(
sk
,
ECONNRESET
);
release_sock
(
sk
);
if
(
!
sk
->
sk_shutdown
)
{
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
l2cap_sock_clear_timer
(
sk
);
__l2cap_sock_close
(
sk
,
0
);
return
0
;
if
(
sock_flag
(
sk
,
SOCK_LINGER
)
&&
sk
->
sk_lingertime
)
err
=
bt_sock_wait_state
(
sk
,
BT_CLOSED
,
sk
->
sk_lingertime
);
}
release_sock
(
sk
);
return
err
;
}
static
int
l2cap_sock_release
(
struct
socket
*
sock
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
err
=
l2cap_sock_shutdown
(
sock
,
2
);
sock_orphan
(
sk
);
l2cap_sock_
close
(
sk
);
return
0
;
l2cap_sock_
kill
(
sk
);
return
err
;
}
/* ---- L2CAP channels ---- */
...
...
@@ -981,9 +986,11 @@ static void l2cap_chan_del(struct sock *sk, int err)
hci_conn_put
(
conn
->
hcon
);
}
sk
->
sk_state
=
BT_CLOSED
;
sk
->
sk_err
=
err
;
sk
->
sk_state
=
BT_CLOSED
;
sk
->
sk_zapped
=
1
;
if
(
err
)
sk
->
sk_err
=
err
;
if
(
parent
)
parent
->
sk_data_ready
(
parent
,
0
);
...
...
@@ -1519,18 +1526,35 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if
(
!
(
sk
=
l2cap_get_chan_by_scid
(
&
conn
->
chan_list
,
scid
)))
return
-
ENOENT
;
if
(
result
)
{
struct
l2cap_disconn_req
req
;
switch
(
result
)
{
case
L2CAP_CONF_SUCCESS
:
break
;
/* They didn't like our options. Well... we do not negotiate.
* Close channel.
*/
case
L2CAP_CONF_UNACCEPT
:
if
(
++
l2cap_pi
(
sk
)
->
conf_retry
<
L2CAP_CONF_MAX_RETRIES
)
{
char
req
[
128
];
/*
It does not make sense to adjust L2CAP parameters
that are currently defined in the spec. We simply
resend config request that we sent earlier. It is
stupid :) but it helps qualification testing
which expects at least some response from us.
*/
l2cap_send_req
(
conn
,
L2CAP_CONF_REQ
,
l2cap_build_conf_req
(
sk
,
req
),
req
);
goto
done
;
}
default:
sk
->
sk_state
=
BT_DISCONN
;
sk
->
sk_err
=
ECONNRESET
;
l2cap_sock_set_timer
(
sk
,
HZ
*
5
);
req
.
dcid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
dcid
);
req
.
scid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
l2cap_send_req
(
conn
,
L2CAP_DISCONN_REQ
,
sizeof
(
req
),
&
req
);
{
struct
l2cap_disconn_req
req
;
req
.
dcid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
dcid
);
req
.
scid
=
__cpu_to_le16
(
l2cap_pi
(
sk
)
->
scid
);
l2cap_send_req
(
conn
,
L2CAP_DISCONN_REQ
,
sizeof
(
req
),
&
req
);
}
goto
done
;
}
...
...
@@ -1591,7 +1615,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
if
(
!
(
sk
=
l2cap_get_chan_by_scid
(
&
conn
->
chan_list
,
scid
)))
return
0
;
l2cap_chan_del
(
sk
,
ECONNABORTED
);
l2cap_chan_del
(
sk
,
0
);
bh_unlock_sock
(
sk
);
l2cap_sock_kill
(
sk
);
...
...
net/bluetooth/rfcomm/core.c
View file @
6e21ae5b
...
...
@@ -280,13 +280,13 @@ static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
static
int
__rfcomm_dlc_open
(
struct
rfcomm_dlc
*
d
,
bdaddr_t
*
src
,
bdaddr_t
*
dst
,
u8
channel
)
{
struct
rfcomm_session
*
s
;
u8
dlci
=
__dlci
(
0
,
channel
);
int
err
=
0
;
u8
dlci
;
BT_DBG
(
"dlc %p state %ld %s %s channel %d
dlci %d
"
,
d
,
d
->
state
,
batostr
(
src
),
batostr
(
dst
),
channel
,
dlci
);
BT_DBG
(
"dlc %p state %ld %s %s channel %d"
,
d
,
d
->
state
,
batostr
(
src
),
batostr
(
dst
),
channel
);
if
(
dlci
<
1
||
dlci
>
62
)
if
(
channel
<
1
||
channel
>
30
)
return
-
EINVAL
;
if
(
d
->
state
!=
BT_OPEN
&&
d
->
state
!=
BT_CLOSED
)
...
...
@@ -299,6 +299,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
return
err
;
}
dlci
=
__dlci
(
!
s
->
initiator
,
channel
);
/* Check if DLCI already exists */
if
(
rfcomm_dlc_get
(
s
,
dlci
))
return
-
EBUSY
;
...
...
@@ -715,7 +717,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
hdr
->
len
=
__len8
(
sizeof
(
*
mcc
)
+
1
);
mcc
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
mcc
);
mcc
->
type
=
__mcc_type
(
s
->
initiato
r
,
RFCOMM_NSC
);
mcc
->
type
=
__mcc_type
(
c
r
,
RFCOMM_NSC
);
mcc
->
len
=
__len8
(
1
);
/* Type that we didn't like */
...
...
@@ -741,7 +743,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
hdr
->
len
=
__len8
(
sizeof
(
*
mcc
)
+
sizeof
(
*
pn
));
mcc
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
mcc
);
mcc
->
type
=
__mcc_type
(
s
->
initiato
r
,
RFCOMM_PN
);
mcc
->
type
=
__mcc_type
(
c
r
,
RFCOMM_PN
);
mcc
->
len
=
__len8
(
sizeof
(
*
pn
));
pn
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
pn
);
...
...
@@ -850,7 +852,51 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig
msc
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
msc
);
msc
->
dlci
=
__addr
(
1
,
dlci
);
msc
->
v24_sig
=
v24_sig
;
msc
->
v24_sig
=
v24_sig
|
0x01
;
*
ptr
=
__fcs
(
buf
);
ptr
++
;
return
rfcomm_send_frame
(
s
,
buf
,
ptr
-
buf
);
}
static
int
rfcomm_send_fcoff
(
struct
rfcomm_session
*
s
,
int
cr
)
{
struct
rfcomm_hdr
*
hdr
;
struct
rfcomm_mcc
*
mcc
;
u8
buf
[
16
],
*
ptr
=
buf
;
BT_DBG
(
"%p cr %d"
,
s
,
cr
);
hdr
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
hdr
);
hdr
->
addr
=
__addr
(
s
->
initiator
,
0
);
hdr
->
ctrl
=
__ctrl
(
RFCOMM_UIH
,
0
);
hdr
->
len
=
__len8
(
sizeof
(
*
mcc
));
mcc
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
mcc
);
mcc
->
type
=
__mcc_type
(
cr
,
RFCOMM_FCOFF
);
mcc
->
len
=
__len8
(
0
);
*
ptr
=
__fcs
(
buf
);
ptr
++
;
return
rfcomm_send_frame
(
s
,
buf
,
ptr
-
buf
);
}
static
int
rfcomm_send_fcon
(
struct
rfcomm_session
*
s
,
int
cr
)
{
struct
rfcomm_hdr
*
hdr
;
struct
rfcomm_mcc
*
mcc
;
u8
buf
[
16
],
*
ptr
=
buf
;
BT_DBG
(
"%p cr %d"
,
s
,
cr
);
hdr
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
hdr
);
hdr
->
addr
=
__addr
(
s
->
initiator
,
0
);
hdr
->
ctrl
=
__ctrl
(
RFCOMM_UIH
,
0
);
hdr
->
len
=
__len8
(
sizeof
(
*
mcc
));
mcc
=
(
void
*
)
ptr
;
ptr
+=
sizeof
(
*
mcc
);
mcc
->
type
=
__mcc_type
(
cr
,
RFCOMM_FCON
);
mcc
->
len
=
__len8
(
0
);
*
ptr
=
__fcs
(
buf
);
ptr
++
;
...
...
@@ -1085,6 +1131,8 @@ static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
d
->
state
=
BT_CONNECTED
;
d
->
state_change
(
d
,
0
);
rfcomm_dlc_unlock
(
d
);
rfcomm_send_msc
(
s
,
1
,
dlci
,
d
->
v24_sig
);
}
else
{
rfcomm_send_dm
(
s
,
dlci
);
}
...
...
@@ -1207,6 +1255,14 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
}
/* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
no flow control lines, normal XON/XOFF chars */
if
(
rpn
->
param_mask
&
RFCOMM_RPN_PM_BITRATE
)
{
bit_rate
=
rpn
->
bit_rate
;
if
(
bit_rate
!=
RFCOMM_RPN_BR_115200
)
{
BT_DBG
(
"RPN bit rate mismatch 0x%x"
,
bit_rate
);
bit_rate
=
RFCOMM_RPN_BR_115200
;
rpn_mask
^=
RFCOMM_RPN_PM_BITRATE
;
}
}
if
(
rpn
->
param_mask
&
RFCOMM_RPN_PM_DATA
)
{
data_bits
=
__get_rpn_data_bits
(
rpn
->
line_settings
);
if
(
data_bits
!=
RFCOMM_RPN_DATA_8
)
{
...
...
@@ -1232,22 +1288,25 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
}
}
if
(
rpn
->
param_mask
&
RFCOMM_RPN_PM_FLOW
)
{
if
(
rpn
->
flow_ctrl
!=
RFCOMM_RPN_FLOW_NONE
)
{
BT_DBG
(
"RPN flow ctrl mismatch 0x%x"
,
rpn
->
flow_ctrl
);
flow_ctrl
=
rpn
->
flow_ctrl
;
if
(
flow_ctrl
!=
RFCOMM_RPN_FLOW_NONE
)
{
BT_DBG
(
"RPN flow ctrl mismatch 0x%x"
,
flow_ctrl
);
flow_ctrl
=
RFCOMM_RPN_FLOW_NONE
;
rpn_mask
^=
RFCOMM_RPN_PM_FLOW
;
}
}
if
(
rpn
->
param_mask
&
RFCOMM_RPN_PM_XON
)
{
if
(
rpn
->
xon_char
!=
RFCOMM_RPN_XON_CHAR
)
{
BT_DBG
(
"RPN XON char mismatch 0x%x"
,
rpn
->
xon_char
);
xon_char
=
rpn
->
xon_char
;
if
(
xon_char
!=
RFCOMM_RPN_XON_CHAR
)
{
BT_DBG
(
"RPN XON char mismatch 0x%x"
,
xon_char
);
xon_char
=
RFCOMM_RPN_XON_CHAR
;
rpn_mask
^=
RFCOMM_RPN_PM_XON
;
}
}
if
(
rpn
->
param_mask
&
RFCOMM_RPN_PM_XOFF
)
{
if
(
rpn
->
xoff_char
!=
RFCOMM_RPN_XOFF_CHAR
)
{
BT_DBG
(
"RPN XOFF char mismatch 0x%x"
,
rpn
->
xoff_char
);
xoff_char
=
rpn
->
xoff_char
;
if
(
xoff_char
!=
RFCOMM_RPN_XOFF_CHAR
)
{
BT_DBG
(
"RPN XOFF char mismatch 0x%x"
,
xoff_char
);
xoff_char
=
RFCOMM_RPN_XOFF_CHAR
;
rpn_mask
^=
RFCOMM_RPN_PM_XOFF
;
}
...
...
@@ -1343,6 +1402,20 @@ static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
rfcomm_recv_msc
(
s
,
cr
,
skb
);
break
;
case
RFCOMM_FCOFF
:
if
(
cr
)
{
set_bit
(
RFCOMM_TX_THROTTLED
,
&
s
->
flags
);
rfcomm_send_fcoff
(
s
,
0
);
}
break
;
case
RFCOMM_FCON
:
if
(
cr
)
{
clear_bit
(
RFCOMM_TX_THROTTLED
,
&
s
->
flags
);
rfcomm_send_fcon
(
s
,
0
);
}
break
;
case
RFCOMM_TEST
:
if
(
cr
)
rfcomm_send_test
(
s
,
0
,
skb
->
data
,
skb
->
len
);
...
...
@@ -1533,6 +1606,9 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue
;
}
if
(
test_bit
(
RFCOMM_TX_THROTTLED
,
&
s
->
flags
))
continue
;
if
((
d
->
state
==
BT_CONNECTED
||
d
->
state
==
BT_DISCONN
)
&&
d
->
mscex
==
RFCOMM_MSCEX_OK
)
rfcomm_process_tx
(
d
);
...
...
net/bluetooth/rfcomm/sock.c
View file @
6e21ae5b
...
...
@@ -193,8 +193,10 @@ static void rfcomm_sock_cleanup_listen(struct sock *parent)
BT_DBG
(
"parent %p"
,
parent
);
/* Close not yet accepted dlcs */
while
((
sk
=
bt_accept_dequeue
(
parent
,
NULL
)))
while
((
sk
=
bt_accept_dequeue
(
parent
,
NULL
)))
{
rfcomm_sock_close
(
sk
);
rfcomm_sock_kill
(
sk
);
}
parent
->
sk_state
=
BT_CLOSED
;
parent
->
sk_zapped
=
1
;
...
...
@@ -216,15 +218,10 @@ static void rfcomm_sock_kill(struct sock *sk)
sock_put
(
sk
);
}
/* Close socket.
* Must be called on unlocked socket.
*/
static
void
rfcomm_sock_close
(
struct
sock
*
sk
)
static
void
__rfcomm_sock_close
(
struct
sock
*
sk
)
{
struct
rfcomm_dlc
*
d
=
rfcomm_pi
(
sk
)
->
dlc
;
lock_sock
(
sk
);
BT_DBG
(
"sk %p state %d socket %p"
,
sk
,
sk
->
sk_state
,
sk
->
sk_socket
);
switch
(
sk
->
sk_state
)
{
...
...
@@ -241,11 +238,17 @@ static void rfcomm_sock_close(struct sock *sk)
default:
sk
->
sk_zapped
=
1
;
break
;
};
}
}
/* Close socket.
* Must be called on unlocked socket.
*/
static
void
rfcomm_sock_close
(
struct
sock
*
sk
)
{
lock_sock
(
sk
);
__rfcomm_sock_close
(
sk
);
release_sock
(
sk
);
rfcomm_sock_kill
(
sk
);
}
static
void
rfcomm_sock_init
(
struct
sock
*
sk
,
struct
sock
*
parent
)
...
...
@@ -375,7 +378,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
err
=
rfcomm_dlc_open
(
d
,
&
bt_sk
(
sk
)
->
src
,
&
sa
->
rc_bdaddr
,
sa
->
rc_channel
);
if
(
!
err
)
err
=
bt_sock_w4_connect
(
sk
,
flags
);
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
));
release_sock
(
sk
);
return
err
;
...
...
@@ -559,9 +563,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
int
target
,
err
=
0
,
copied
=
0
;
long
timeo
;
if
(
sk
->
sk_state
!=
BT_CONNECTED
)
return
-
EINVAL
;
if
(
flags
&
MSG_OOB
)
return
-
EOPNOTSUPP
;
...
...
@@ -636,23 +637,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return
copied
?
:
err
;
}
static
int
rfcomm_sock_shutdown
(
struct
socket
*
sock
,
int
how
)
{
struct
sock
*
sk
=
sock
->
sk
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
lock_sock
(
sk
);
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
if
(
sk
->
sk_state
==
BT_CONNECTED
)
rfcomm_dlc_close
(
rfcomm_pi
(
sk
)
->
dlc
,
0
);
release_sock
(
sk
);
return
0
;
}
static
int
rfcomm_sock_setsockopt
(
struct
socket
*
sock
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
{
struct
sock
*
sk
=
sock
->
sk
;
...
...
@@ -711,19 +695,42 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
return
err
;
}
static
int
rfcomm_sock_shutdown
(
struct
socket
*
sock
,
int
how
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
lock_sock
(
sk
);
if
(
!
sk
->
sk_shutdown
)
{
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
__rfcomm_sock_close
(
sk
);
if
(
sock_flag
(
sk
,
SOCK_LINGER
)
&&
sk
->
sk_lingertime
)
err
=
bt_sock_wait_state
(
sk
,
BT_CLOSED
,
sk
->
sk_lingertime
);
}
release_sock
(
sk
);
return
err
;
}
static
int
rfcomm_sock_release
(
struct
socket
*
sock
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
sock_orphan
(
sk
);
rfcomm_sock_close
(
sk
);
err
=
rfcomm_sock_shutdown
(
sock
,
2
);
return
0
;
sock_orphan
(
sk
);
rfcomm_sock_kill
(
sk
);
return
err
;
}
/* ---- RFCOMM core layer callbacks ----
...
...
net/bluetooth/rfcomm/tty.c
View file @
6e21ae5b
...
...
@@ -668,40 +668,8 @@ static int rfcomm_tty_write_room(struct tty_struct *tty)
return
room
;
}
static
int
rfcomm_tty_set_modem_status
(
uint
cmd
,
struct
rfcomm_dlc
*
dlc
,
uint
status
)
{
u8
v24_sig
,
mask
;
BT_DBG
(
"dlc %p cmd 0x%02x"
,
dlc
,
cmd
);
if
(
cmd
==
TIOCMSET
)
v24_sig
=
0
;
else
rfcomm_dlc_get_modem_status
(
dlc
,
&
v24_sig
);
mask
=
((
status
&
TIOCM_DSR
)
?
RFCOMM_V24_RTC
:
0
)
|
((
status
&
TIOCM_DTR
)
?
RFCOMM_V24_RTC
:
0
)
|
((
status
&
TIOCM_RTS
)
?
RFCOMM_V24_RTR
:
0
)
|
((
status
&
TIOCM_CTS
)
?
RFCOMM_V24_RTR
:
0
)
|
((
status
&
TIOCM_RI
)
?
RFCOMM_V24_IC
:
0
)
|
((
status
&
TIOCM_CD
)
?
RFCOMM_V24_DV
:
0
);
if
(
cmd
==
TIOCMBIC
)
v24_sig
&=
~
mask
;
else
v24_sig
|=
mask
;
rfcomm_dlc_set_modem_status
(
dlc
,
v24_sig
);
return
0
;
}
static
int
rfcomm_tty_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
rfcomm_dev
*
dev
=
(
struct
rfcomm_dev
*
)
tty
->
driver_data
;
struct
rfcomm_dlc
*
dlc
=
dev
->
dlc
;
uint
status
;
int
err
;
BT_DBG
(
"tty %p cmd 0x%02x"
,
tty
,
cmd
);
switch
(
cmd
)
{
...
...
@@ -713,18 +681,6 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned
BT_DBG
(
"TCSETS is not supported"
);
return
-
ENOIOCTLCMD
;
case
TIOCMGET
:
BT_DBG
(
"TIOCMGET"
);
return
put_user
(
dev
->
modem_status
,
(
unsigned
int
*
)
arg
);
case
TIOCMSET
:
/* Turns on and off the lines as specified by the mask */
case
TIOCMBIS
:
/* Turns on the lines as specified by the mask */
case
TIOCMBIC
:
/* Turns off the lines as specified by the mask */
if
((
err
=
get_user
(
status
,
(
unsigned
int
*
)
arg
)))
return
err
;
return
rfcomm_tty_set_modem_status
(
cmd
,
dlc
,
status
);
case
TIOCMIWAIT
:
BT_DBG
(
"TIOCMIWAIT"
);
break
;
...
...
@@ -851,6 +807,48 @@ static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
return
0
;
}
static
int
rfcomm_tty_tiocmget
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
struct
rfcomm_dev
*
dev
=
(
struct
rfcomm_dev
*
)
tty
->
driver_data
;
BT_DBG
(
"tty %p dev %p"
,
tty
,
dev
);
return
dev
->
modem_status
;
}
static
int
rfcomm_tty_tiocmset
(
struct
tty_struct
*
tty
,
struct
file
*
filp
,
unsigned
int
set
,
unsigned
int
clear
)
{
struct
rfcomm_dev
*
dev
=
(
struct
rfcomm_dev
*
)
tty
->
driver_data
;
struct
rfcomm_dlc
*
dlc
=
dev
->
dlc
;
u8
v24_sig
;
BT_DBG
(
"tty %p dev %p set 0x%02x clear 0x%02x"
,
tty
,
dev
,
set
,
clear
);
rfcomm_dlc_get_modem_status
(
dlc
,
&
v24_sig
);
if
(
set
&
TIOCM_DSR
||
set
&
TIOCM_DTR
)
v24_sig
|=
RFCOMM_V24_RTC
;
if
(
set
&
TIOCM_RTS
||
set
&
TIOCM_CTS
)
v24_sig
|=
RFCOMM_V24_RTR
;
if
(
set
&
TIOCM_RI
)
v24_sig
|=
RFCOMM_V24_IC
;
if
(
set
&
TIOCM_CD
)
v24_sig
|=
RFCOMM_V24_DV
;
if
(
clear
&
TIOCM_DSR
||
clear
&
TIOCM_DTR
)
v24_sig
&=
~
RFCOMM_V24_RTC
;
if
(
clear
&
TIOCM_RTS
||
clear
&
TIOCM_CTS
)
v24_sig
&=
~
RFCOMM_V24_RTR
;
if
(
clear
&
TIOCM_RI
)
v24_sig
&=
~
RFCOMM_V24_IC
;
if
(
clear
&
TIOCM_CD
)
v24_sig
&=
~
RFCOMM_V24_DV
;
rfcomm_dlc_set_modem_status
(
dlc
,
v24_sig
);
return
0
;
}
/* ---- TTY structure ---- */
static
struct
tty_driver
*
rfcomm_tty_driver
;
...
...
@@ -870,6 +868,8 @@ static struct tty_operations rfcomm_ops = {
.
hangup
=
rfcomm_tty_hangup
,
.
wait_until_sent
=
rfcomm_tty_wait_until_sent
,
.
read_proc
=
rfcomm_tty_read_proc
,
.
tiocmget
=
rfcomm_tty_tiocmget
,
.
tiocmset
=
rfcomm_tty_tiocmset
,
};
int
rfcomm_init_ttys
(
void
)
...
...
@@ -878,18 +878,17 @@ int rfcomm_init_ttys(void)
if
(
!
rfcomm_tty_driver
)
return
-
1
;
rfcomm_tty_driver
->
owner
=
THIS_MODULE
,
rfcomm_tty_driver
->
driver_name
=
"rfcomm"
,
rfcomm_tty_driver
->
devfs_name
=
"bluetooth/rfcomm/"
,
rfcomm_tty_driver
->
name
=
"rfcomm"
,
rfcomm_tty_driver
->
major
=
RFCOMM_TTY_MAJOR
,
rfcomm_tty_driver
->
minor_start
=
RFCOMM_TTY_MINOR
,
rfcomm_tty_driver
->
type
=
TTY_DRIVER_TYPE_SERIAL
,
rfcomm_tty_driver
->
subtype
=
SERIAL_TYPE_NORMAL
,
rfcomm_tty_driver
->
flags
=
TTY_DRIVER_REAL_RAW
,
rfcomm_tty_driver
->
init_termios
=
tty_std_termios
;
rfcomm_tty_driver
->
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
|
CLOCAL
;
rfcomm_tty_driver
->
flags
=
TTY_DRIVER_REAL_RAW
;
rfcomm_tty_driver
->
owner
=
THIS_MODULE
;
rfcomm_tty_driver
->
driver_name
=
"rfcomm"
;
rfcomm_tty_driver
->
devfs_name
=
"bluetooth/rfcomm/"
;
rfcomm_tty_driver
->
name
=
"rfcomm"
;
rfcomm_tty_driver
->
major
=
RFCOMM_TTY_MAJOR
;
rfcomm_tty_driver
->
minor_start
=
RFCOMM_TTY_MINOR
;
rfcomm_tty_driver
->
type
=
TTY_DRIVER_TYPE_SERIAL
;
rfcomm_tty_driver
->
subtype
=
SERIAL_TYPE_NORMAL
;
rfcomm_tty_driver
->
flags
=
TTY_DRIVER_REAL_RAW
;
rfcomm_tty_driver
->
init_termios
=
tty_std_termios
;
rfcomm_tty_driver
->
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
|
CLOCAL
;
tty_set_operations
(
rfcomm_tty_driver
,
&
rfcomm_ops
);
if
(
tty_register_driver
(
rfcomm_tty_driver
))
{
...
...
net/bluetooth/sco.c
View file @
6e21ae5b
...
...
@@ -354,8 +354,10 @@ static void sco_sock_cleanup_listen(struct sock *parent)
BT_DBG
(
"parent %p"
,
parent
);
/* Close not yet accepted channels */
while
((
sk
=
bt_accept_dequeue
(
parent
,
NULL
)))
while
((
sk
=
bt_accept_dequeue
(
parent
,
NULL
)))
{
sco_sock_close
(
sk
);
sco_sock_kill
(
sk
);
}
parent
->
sk_state
=
BT_CLOSED
;
parent
->
sk_zapped
=
1
;
...
...
@@ -524,7 +526,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
if
((
err
=
sco_connect
(
sk
)))
goto
done
;
err
=
bt_sock_w4_connect
(
sk
,
flags
);
err
=
bt_sock_wait_state
(
sk
,
BT_CONNECTED
,
sock_sndtimeo
(
sk
,
flags
&
O_NONBLOCK
));
done:
release_sock
(
sk
);
...
...
@@ -728,16 +731,24 @@ int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
static
int
sco_sock_release
(
struct
socket
*
sock
)
{
struct
sock
*
sk
=
sock
->
sk
;
int
err
=
0
;
BT_DBG
(
"sock %p, sk %p"
,
sock
,
sk
);
if
(
!
sk
)
return
0
;
sock_orphan
(
sk
);
sco_sock_close
(
sk
);
return
0
;
if
(
sock_flag
(
sk
,
SOCK_LINGER
)
&&
sk
->
sk_lingertime
)
{
lock_sock
(
sk
);
err
=
bt_sock_wait_state
(
sk
,
BT_CLOSED
,
sk
->
sk_lingertime
);
release_sock
(
sk
);
}
sock_orphan
(
sk
);
sco_sock_kill
(
sk
);
return
err
;
}
static
void
__sco_chan_add
(
struct
sco_conn
*
conn
,
struct
sock
*
sk
,
struct
sock
*
parent
)
...
...
net/bluetooth/syms.c
View file @
6e21ae5b
...
...
@@ -77,6 +77,6 @@ EXPORT_SYMBOL(bt_sock_recvmsg);
EXPORT_SYMBOL
(
bt_sock_poll
);
EXPORT_SYMBOL
(
bt_accept_enqueue
);
EXPORT_SYMBOL
(
bt_accept_dequeue
);
EXPORT_SYMBOL
(
bt_sock_w
4_connect
);
EXPORT_SYMBOL
(
bt_sock_w
ait_state
);
EXPORT_SYMBOL
(
proc_bt
);
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