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
037f7f39
Commit
037f7f39
authored
Jun 16, 2003
by
Maksim Krasnyanskiy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Bluetooth] Add support for SO_LINGER to L2CAP, RFCOMM and SCO sockets.
This is required to pass qualification testing.
parent
8c473eea
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
91 additions
and
72 deletions
+91
-72
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluetooth.h
+1
-1
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+9
-13
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+23
-16
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/sock.c
+41
-34
net/bluetooth/rfcomm/tty.c
net/bluetooth/rfcomm/tty.c
+0
-2
net/bluetooth/sco.c
net/bluetooth/sco.c
+16
-5
net/bluetooth/syms.c
net/bluetooth/syms.c
+1
-1
No files found.
include/net/bluetooth/bluetooth.h
View file @
037f7f39
...
...
@@ -130,7 +130,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
);
...
...
net/bluetooth/af_bluetooth.c
View file @
037f7f39
...
...
@@ -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>
...
...
@@ -282,39 +282,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/l2cap.c
View file @
037f7f39
...
...
@@ -287,7 +287,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
);
...
...
@@ -312,11 +312,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
);
}
...
...
@@ -528,8 +526,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
;
...
...
@@ -829,32 +827,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
);
if
(
!
sk
->
sk_shutdown
)
{
sk
->
sk_shutdown
=
SHUTDOWN_MASK
;
__l2cap_sock_close
(
sk
,
ECONNRESET
);
release_sock
(
sk
);
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 ---- */
...
...
@@ -979,9 +984,11 @@ static void l2cap_chan_del(struct sock *sk, int err)
}
sk
->
sk_state
=
BT_CLOSED
;
sk
->
sk_err
=
err
;
sk
->
sk_zapped
=
1
;
if
(
err
)
sk
->
sk_err
=
err
;
if
(
parent
)
parent
->
sk_data_ready
(
parent
,
0
);
else
...
...
@@ -1588,7 +1595,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/sock.c
View file @
037f7f39
...
...
@@ -191,8 +191,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
;
...
...
@@ -214,15 +216,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
)
{
...
...
@@ -239,11 +236,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
)
...
...
@@ -373,7 +376,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
;
...
...
@@ -557,9 +561,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
;
...
...
@@ -634,23 +635,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
;
...
...
@@ -709,19 +693,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 @
037f7f39
...
...
@@ -874,8 +874,6 @@ static struct tty_operations rfcomm_ops = {
int
rfcomm_init_ttys
(
void
)
{
int
i
;
rfcomm_tty_driver
=
alloc_tty_driver
(
RFCOMM_TTY_PORTS
);
if
(
!
rfcomm_tty_driver
)
return
-
1
;
...
...
net/bluetooth/sco.c
View file @
037f7f39
...
...
@@ -352,8 +352,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
;
...
...
@@ -522,7 +524,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
);
...
...
@@ -726,16 +729,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 @
037f7f39
...
...
@@ -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