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
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