2011-02-04 01:50:35 +03:00
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright ( C ) 2000 - 2001 Qualcomm Incorporated
Copyright ( C ) 2009 - 2010 Gustavo F . Padovan < gustavo @ padovan . org >
Copyright ( C ) 2010 Google Inc .
2011-12-18 19:39:33 +04:00
Copyright ( C ) 2011 ProFUSION Embedded Systems
2011-02-04 01:50:35 +03:00
Written 2000 , 2001 by Maxim Krasnyansky < maxk @ qualcomm . com >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation ;
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS
OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS .
IN NO EVENT SHALL THE COPYRIGHT HOLDER ( S ) AND AUTHOR ( S ) BE LIABLE FOR ANY
CLAIM , OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES , OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
ALL LIABILITY , INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS ,
COPYRIGHTS , TRADEMARKS OR OTHER RIGHTS , RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED .
*/
/* Bluetooth L2CAP sockets. */
2013-12-02 13:20:20 +04:00
# include <linux/module.h>
2011-07-15 19:47:34 +04:00
# include <linux/export.h>
2011-10-07 13:40:59 +04:00
2011-02-04 01:50:35 +03:00
# include <net/bluetooth/bluetooth.h>
2011-02-04 07:48:48 +03:00
# include <net/bluetooth/hci_core.h>
2011-02-04 01:50:35 +03:00
# include <net/bluetooth/l2cap.h>
2013-10-11 01:54:16 +04:00
# include "smp.h"
2011-02-04 01:50:35 +03:00
2013-12-02 13:20:20 +04:00
bool enable_lecoc ;
2012-07-25 20:29:25 +04:00
static struct bt_sock_list l2cap_sk_list = {
. lock = __RW_LOCK_UNLOCKED ( l2cap_sk_list . lock )
} ;
2011-04-28 01:40:39 +04:00
static const struct proto_ops l2cap_sock_ops ;
2011-05-17 00:24:37 +04:00
static void l2cap_sock_init ( struct sock * sk , struct sock * parent ) ;
2012-10-06 13:07:01 +04:00
static struct sock * l2cap_sock_alloc ( struct net * net , struct socket * sock ,
int proto , gfp_t prio ) ;
2011-04-28 01:40:39 +04:00
2013-04-05 16:57:34 +04:00
bool l2cap_is_socket ( struct socket * sock )
{
return sock & & sock - > ops = = & l2cap_sock_ops ;
}
EXPORT_SYMBOL ( l2cap_is_socket ) ;
2013-10-08 15:55:46 +04:00
static int l2cap_validate_bredr_psm ( u16 psm )
{
/* PSM must be odd and lsb of upper byte must be 0 */
if ( ( psm & 0x0101 ) ! = 0x0001 )
return - EINVAL ;
/* Restrict usage of well-known PSMs */
if ( psm < 0x1001 & & ! capable ( CAP_NET_BIND_SERVICE ) )
return - EACCES ;
return 0 ;
}
static int l2cap_validate_le_psm ( u16 psm )
{
/* Valid LE_PSM ranges are defined only until 0x00ff */
if ( psm > 0x00ff )
return - EINVAL ;
/* Restrict fixed, SIG assigned PSM values to CAP_NET_BIND_SERVICE */
if ( psm < = 0x007f & & ! capable ( CAP_NET_BIND_SERVICE ) )
return - EACCES ;
return 0 ;
}
2011-02-04 07:40:28 +03:00
static int l2cap_sock_bind ( struct socket * sock , struct sockaddr * addr , int alen )
{
struct sock * sk = sock - > sk ;
2011-04-13 01:31:57 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:40:28 +03:00
struct sockaddr_l2 la ;
int len , err = 0 ;
BT_DBG ( " sk %p " , sk ) ;
if ( ! addr | | addr - > sa_family ! = AF_BLUETOOTH )
return - EINVAL ;
memset ( & la , 0 , sizeof ( la ) ) ;
len = min_t ( unsigned int , sizeof ( la ) , alen ) ;
memcpy ( & la , addr , len ) ;
2011-02-11 04:38:50 +03:00
if ( la . l2_cid & & la . l2_psm )
2011-02-04 07:40:28 +03:00
return - EINVAL ;
2013-10-14 22:17:52 +04:00
if ( ! bdaddr_type_is_valid ( la . l2_bdaddr_type ) )
return - EINVAL ;
2014-01-24 12:35:41 +04:00
if ( la . l2_cid ) {
/* When the socket gets created it defaults to
* CHAN_CONN_ORIENTED , so we need to overwrite the
* default here .
*/
chan - > chan_type = L2CAP_CHAN_FIXED ;
chan - > omtu = L2CAP_DEFAULT_MTU ;
}
2013-10-16 18:13:26 +04:00
if ( bdaddr_type_is_le ( la . l2_bdaddr_type ) ) {
2013-12-02 13:20:20 +04:00
if ( ! enable_lecoc & & la . l2_psm )
2013-10-16 18:13:26 +04:00
return - EINVAL ;
/* We only allow ATT user space socket */
2013-12-02 13:20:20 +04:00
if ( la . l2_cid & &
la . l2_cid ! = __constant_cpu_to_le16 ( L2CAP_CID_ATT ) )
2013-10-16 18:13:26 +04:00
return - EINVAL ;
}
2011-02-04 07:40:28 +03:00
lock_sock ( sk ) ;
if ( sk - > sk_state ! = BT_OPEN ) {
err = - EBADFD ;
goto done ;
}
if ( la . l2_psm ) {
__u16 psm = __le16_to_cpu ( la . l2_psm ) ;
2013-10-08 15:55:46 +04:00
if ( la . l2_bdaddr_type = = BDADDR_BREDR )
err = l2cap_validate_bredr_psm ( psm ) ;
else
err = l2cap_validate_le_psm ( psm ) ;
2011-02-04 07:40:28 +03:00
2013-10-08 15:55:46 +04:00
if ( err )
2011-02-04 07:40:28 +03:00
goto done ;
}
2011-04-19 01:38:43 +04:00
if ( la . l2_cid )
2012-03-01 21:16:36 +04:00
err = l2cap_add_scid ( chan , __le16_to_cpu ( la . l2_cid ) ) ;
2011-04-19 01:38:43 +04:00
else
err = l2cap_add_psm ( chan , & la . l2_bdaddr , la . l2_psm ) ;
2011-02-04 07:40:28 +03:00
2011-04-19 01:38:43 +04:00
if ( err < 0 )
goto done ;
2011-02-04 07:40:28 +03:00
2013-10-12 18:19:31 +04:00
switch ( chan - > chan_type ) {
2013-10-12 18:19:32 +04:00
case L2CAP_CHAN_CONN_LESS :
if ( __le16_to_cpu ( la . l2_psm ) = = L2CAP_PSM_3DSP )
chan - > sec_level = BT_SECURITY_SDP ;
break ;
2013-10-12 18:19:31 +04:00
case L2CAP_CHAN_CONN_ORIENTED :
if ( __le16_to_cpu ( la . l2_psm ) = = L2CAP_PSM_SDP | |
__le16_to_cpu ( la . l2_psm ) = = L2CAP_PSM_RFCOMM )
chan - > sec_level = BT_SECURITY_SDP ;
break ;
2014-01-06 20:27:02 +04:00
case L2CAP_CHAN_RAW :
chan - > sec_level = BT_SECURITY_SDP ;
break ;
2013-10-12 18:19:31 +04:00
}
2011-02-11 04:38:50 +03:00
2013-10-13 19:12:47 +04:00
bacpy ( & chan - > src , & la . l2_bdaddr ) ;
2013-10-13 19:50:41 +04:00
chan - > src_type = la . l2_bdaddr_type ;
2011-06-03 07:19:47 +04:00
2013-05-17 13:49:23 +04:00
if ( chan - > psm & & bdaddr_type_is_le ( chan - > src_type ) )
2013-12-05 16:55:33 +04:00
chan - > mode = L2CAP_MODE_LE_FLOWCTL ;
2013-05-17 13:49:23 +04:00
2011-06-03 07:19:47 +04:00
chan - > state = BT_BOUND ;
2011-04-19 01:38:43 +04:00
sk - > sk_state = BT_BOUND ;
2011-02-04 07:40:28 +03:00
done :
release_sock ( sk ) ;
return err ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_connect ( struct socket * sock , struct sockaddr * addr ,
int alen , int flags )
2011-02-04 07:56:13 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-14 00:20:49 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:56:13 +03:00
struct sockaddr_l2 la ;
int len , err = 0 ;
BT_DBG ( " sk %p " , sk ) ;
if ( ! addr | | alen < sizeof ( addr - > sa_family ) | |
addr - > sa_family ! = AF_BLUETOOTH )
return - EINVAL ;
memset ( & la , 0 , sizeof ( la ) ) ;
len = min_t ( unsigned int , sizeof ( la ) , alen ) ;
memcpy ( & la , addr , len ) ;
2011-02-11 04:38:49 +03:00
if ( la . l2_cid & & la . l2_psm )
2011-02-04 07:56:13 +03:00
return - EINVAL ;
2013-10-14 22:17:52 +04:00
if ( ! bdaddr_type_is_valid ( la . l2_bdaddr_type ) )
return - EINVAL ;
2013-10-18 12:49:25 +04:00
/* Check that the socket wasn't bound to something that
* conflicts with the address given to connect ( ) . If chan - > src
* is BDADDR_ANY it means bind ( ) was never used , in which case
* chan - > src_type and la . l2_bdaddr_type do not need to match .
*/
if ( chan - > src_type = = BDADDR_BREDR & & bacmp ( & chan - > src , BDADDR_ANY ) & &
bdaddr_type_is_le ( la . l2_bdaddr_type ) ) {
/* Old user space versions will try to incorrectly bind
* the ATT socket using BDADDR_BREDR . We need to accept
* this and fix up the source address type only when
* both the source CID and destination CID indicate
* ATT . Anything else is an invalid combination .
*/
if ( chan - > scid ! = L2CAP_CID_ATT | |
la . l2_cid ! = __constant_cpu_to_le16 ( L2CAP_CID_ATT ) )
return - EINVAL ;
/* We don't have the hdev available here to make a
* better decision on random vs public , but since all
* user space versions that exhibit this issue anyway do
* not support random local addresses assuming public
* here is good enough .
*/
chan - > src_type = BDADDR_LE_PUBLIC ;
}
2013-10-14 22:17:53 +04:00
if ( chan - > src_type ! = BDADDR_BREDR & & la . l2_bdaddr_type = = BDADDR_BREDR )
return - EINVAL ;
2013-10-16 18:13:26 +04:00
if ( bdaddr_type_is_le ( la . l2_bdaddr_type ) ) {
2013-12-02 13:20:20 +04:00
if ( ! enable_lecoc & & la . l2_psm )
2013-10-16 18:13:26 +04:00
return - EINVAL ;
/* We only allow ATT user space socket */
2013-12-02 13:20:20 +04:00
if ( la . l2_cid & &
la . l2_cid ! = __constant_cpu_to_le16 ( L2CAP_CID_ATT ) )
2013-10-16 18:13:26 +04:00
return - EINVAL ;
}
2013-05-17 13:49:23 +04:00
if ( chan - > psm & & bdaddr_type_is_le ( chan - > src_type ) )
2013-12-05 16:55:33 +04:00
chan - > mode = L2CAP_MODE_LE_FLOWCTL ;
2013-05-17 13:49:23 +04:00
2012-03-01 21:16:36 +04:00
err = l2cap_chan_connect ( chan , la . l2_psm , __le16_to_cpu ( la . l2_cid ) ,
2012-04-25 04:02:55 +04:00
& la . l2_bdaddr , la . l2_bdaddr_type ) ;
2011-02-04 07:56:13 +03:00
if ( err )
2012-02-22 19:11:57 +04:00
return err ;
2011-02-04 07:56:13 +03:00
2012-02-22 19:11:56 +04:00
lock_sock ( sk ) ;
2011-02-04 07:56:13 +03:00
err = bt_sock_wait_state ( sk , BT_CONNECTED ,
2012-10-06 13:07:01 +04:00
sock_sndtimeo ( sk , flags & O_NONBLOCK ) ) ;
2012-02-22 19:11:57 +04:00
release_sock ( sk ) ;
2011-02-04 07:56:13 +03:00
return err ;
}
2011-02-04 07:40:28 +03:00
static int l2cap_sock_listen ( struct socket * sock , int backlog )
{
struct sock * sk = sock - > sk ;
2011-04-14 00:20:49 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:40:28 +03:00
int err = 0 ;
BT_DBG ( " sk %p backlog %d " , sk , backlog ) ;
lock_sock ( sk ) ;
2012-04-19 15:43:51 +04:00
if ( sk - > sk_state ! = BT_BOUND ) {
2011-02-04 07:40:28 +03:00
err = - EBADFD ;
goto done ;
}
2012-04-19 15:43:51 +04:00
if ( sk - > sk_type ! = SOCK_SEQPACKET & & sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
goto done ;
}
2011-04-14 00:20:49 +04:00
switch ( chan - > mode ) {
2011-02-04 07:40:28 +03:00
case L2CAP_MODE_BASIC :
2013-05-17 13:49:23 +04:00
case L2CAP_MODE_LE_FLOWCTL :
2011-02-04 07:40:28 +03:00
break ;
case L2CAP_MODE_ERTM :
case L2CAP_MODE_STREAMING :
if ( ! disable_ertm )
break ;
/* fall through */
default :
err = - ENOTSUPP ;
goto done ;
}
sk - > sk_max_ack_backlog = backlog ;
sk - > sk_ack_backlog = 0 ;
2011-06-03 07:19:47 +04:00
chan - > state = BT_LISTEN ;
2011-02-04 07:40:28 +03:00
sk - > sk_state = BT_LISTEN ;
done :
release_sock ( sk ) ;
return err ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_accept ( struct socket * sock , struct socket * newsock ,
int flags )
2011-02-04 07:42:23 +03:00
{
DECLARE_WAITQUEUE ( wait , current ) ;
struct sock * sk = sock - > sk , * nsk ;
long timeo ;
int err = 0 ;
lock_sock_nested ( sk , SINGLE_DEPTH_NESTING ) ;
timeo = sock_rcvtimeo ( sk , flags & O_NONBLOCK ) ;
BT_DBG ( " sk %p timeo %ld " , sk , timeo ) ;
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive ( sk_sleep ( sk ) , & wait ) ;
2011-07-24 08:10:52 +04:00
while ( 1 ) {
2011-02-04 07:42:23 +03:00
set_current_state ( TASK_INTERRUPTIBLE ) ;
2011-07-24 08:10:52 +04:00
if ( sk - > sk_state ! = BT_LISTEN ) {
err = - EBADFD ;
2011-02-04 07:42:23 +03:00
break ;
}
2011-07-24 08:10:52 +04:00
nsk = bt_accept_dequeue ( sk , newsock ) ;
if ( nsk )
break ;
2011-02-04 07:42:23 +03:00
2011-07-24 08:10:52 +04:00
if ( ! timeo ) {
err = - EAGAIN ;
2011-02-04 07:42:23 +03:00
break ;
}
if ( signal_pending ( current ) ) {
err = sock_intr_errno ( timeo ) ;
break ;
}
2011-07-24 08:10:52 +04:00
release_sock ( sk ) ;
timeo = schedule_timeout ( timeo ) ;
lock_sock_nested ( sk , SINGLE_DEPTH_NESTING ) ;
2011-02-04 07:42:23 +03:00
}
2011-07-24 08:10:52 +04:00
__set_current_state ( TASK_RUNNING ) ;
2011-02-04 07:42:23 +03:00
remove_wait_queue ( sk_sleep ( sk ) , & wait ) ;
if ( err )
goto done ;
newsock - > state = SS_CONNECTED ;
BT_DBG ( " new socket %p " , nsk ) ;
done :
release_sock ( sk ) ;
return err ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_getname ( struct socket * sock , struct sockaddr * addr ,
int * len , int peer )
2011-02-04 07:43:46 +03:00
{
struct sockaddr_l2 * la = ( struct sockaddr_l2 * ) addr ;
struct sock * sk = sock - > sk ;
2011-04-14 00:20:49 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:43:46 +03:00
BT_DBG ( " sock %p, sk %p " , sock , sk ) ;
2012-08-15 15:31:51 +04:00
memset ( la , 0 , sizeof ( struct sockaddr_l2 ) ) ;
2011-02-04 07:43:46 +03:00
addr - > sa_family = AF_BLUETOOTH ;
* len = sizeof ( struct sockaddr_l2 ) ;
if ( peer ) {
2011-04-14 02:50:45 +04:00
la - > l2_psm = chan - > psm ;
2013-10-13 19:12:47 +04:00
bacpy ( & la - > l2_bdaddr , & chan - > dst ) ;
2011-04-14 02:50:45 +04:00
la - > l2_cid = cpu_to_le16 ( chan - > dcid ) ;
2013-10-13 19:50:41 +04:00
la - > l2_bdaddr_type = chan - > dst_type ;
2011-02-04 07:43:46 +03:00
} else {
2011-04-14 00:20:49 +04:00
la - > l2_psm = chan - > sport ;
2013-10-13 19:12:47 +04:00
bacpy ( & la - > l2_bdaddr , & chan - > src ) ;
2011-04-14 02:50:45 +04:00
la - > l2_cid = cpu_to_le16 ( chan - > scid ) ;
2013-10-13 19:50:41 +04:00
la - > l2_bdaddr_type = chan - > src_type ;
2011-02-04 07:43:46 +03:00
}
return 0 ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_getsockopt_old ( struct socket * sock , int optname ,
char __user * optval , int __user * optlen )
2011-02-04 07:52:55 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-13 01:31:57 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:52:55 +03:00
struct l2cap_options opts ;
struct l2cap_conninfo cinfo ;
int len , err = 0 ;
u32 opt ;
BT_DBG ( " sk %p " , sk ) ;
if ( get_user ( len , optlen ) )
return - EFAULT ;
lock_sock ( sk ) ;
switch ( optname ) {
case L2CAP_OPTIONS :
2013-12-02 18:02:03 +04:00
/* LE sockets should use BT_SNDMTU/BT_RCVMTU, but since
* legacy ATT code depends on getsockopt for
* L2CAP_OPTIONS we need to let this pass .
*/
if ( bdaddr_type_is_le ( chan - > src_type ) & &
chan - > scid ! = L2CAP_CID_ATT ) {
err = - EINVAL ;
break ;
}
2011-02-10 20:59:42 +03:00
memset ( & opts , 0 , sizeof ( opts ) ) ;
2011-04-14 00:20:49 +04:00
opts . imtu = chan - > imtu ;
opts . omtu = chan - > omtu ;
opts . flush_to = chan - > flush_to ;
opts . mode = chan - > mode ;
2011-04-13 22:57:03 +04:00
opts . fcs = chan - > fcs ;
opts . max_tx = chan - > max_tx ;
2011-10-11 14:37:42 +04:00
opts . txwin_size = chan - > tx_win ;
2011-02-04 07:52:55 +03:00
len = min_t ( unsigned int , len , sizeof ( opts ) ) ;
if ( copy_to_user ( optval , ( char * ) & opts , len ) )
err = - EFAULT ;
break ;
case L2CAP_LM :
2011-04-13 01:31:57 +04:00
switch ( chan - > sec_level ) {
2011-02-04 07:52:55 +03:00
case BT_SECURITY_LOW :
opt = L2CAP_LM_AUTH ;
break ;
case BT_SECURITY_MEDIUM :
opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT ;
break ;
case BT_SECURITY_HIGH :
opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
2012-10-06 13:07:01 +04:00
L2CAP_LM_SECURE ;
2011-02-04 07:52:55 +03:00
break ;
2014-01-16 10:37:40 +04:00
case BT_SECURITY_FIPS :
opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT |
L2CAP_LM_SECURE | L2CAP_LM_FIPS ;
break ;
2011-02-04 07:52:55 +03:00
default :
opt = 0 ;
break ;
}
2011-10-11 15:04:34 +04:00
if ( test_bit ( FLAG_ROLE_SWITCH , & chan - > flags ) )
2011-02-04 07:52:55 +03:00
opt | = L2CAP_LM_MASTER ;
2011-10-11 15:04:32 +04:00
if ( test_bit ( FLAG_FORCE_RELIABLE , & chan - > flags ) )
2011-02-04 07:52:55 +03:00
opt | = L2CAP_LM_RELIABLE ;
if ( put_user ( opt , ( u32 __user * ) optval ) )
err = - EFAULT ;
2014-01-16 10:37:40 +04:00
2011-02-04 07:52:55 +03:00
break ;
case L2CAP_CONNINFO :
if ( sk - > sk_state ! = BT_CONNECTED & &
2012-05-16 19:17:10 +04:00
! ( sk - > sk_state = = BT_CONNECT2 & &
test_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ) ) {
2011-02-04 07:52:55 +03:00
err = - ENOTCONN ;
break ;
}
2011-05-12 21:32:46 +04:00
memset ( & cinfo , 0 , sizeof ( cinfo ) ) ;
2011-04-14 03:23:55 +04:00
cinfo . hci_handle = chan - > conn - > hcon - > handle ;
memcpy ( cinfo . dev_class , chan - > conn - > hcon - > dev_class , 3 ) ;
2011-02-04 07:52:55 +03:00
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 ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_getsockopt ( struct socket * sock , int level , int optname ,
char __user * optval , int __user * optlen )
2011-02-04 07:52:55 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-13 01:31:57 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:52:55 +03:00
struct bt_security sec ;
2011-05-24 05:06:04 +04:00
struct bt_power pwr ;
2011-02-04 07:52:55 +03:00
int len , err = 0 ;
BT_DBG ( " sk %p " , sk ) ;
if ( level = = SOL_L2CAP )
return l2cap_sock_getsockopt_old ( sock , optname , optval , optlen ) ;
if ( level ! = SOL_BLUETOOTH )
return - ENOPROTOOPT ;
if ( get_user ( len , optlen ) )
return - EFAULT ;
lock_sock ( sk ) ;
switch ( optname ) {
case BT_SECURITY :
2011-05-03 00:13:55 +04:00
if ( chan - > chan_type ! = L2CAP_CHAN_CONN_ORIENTED & &
2012-10-06 13:07:01 +04:00
chan - > chan_type ! = L2CAP_CHAN_RAW ) {
2011-02-04 07:52:55 +03:00
err = - EINVAL ;
break ;
}
2011-07-09 01:31:46 +04:00
memset ( & sec , 0 , sizeof ( sec ) ) ;
2012-10-05 17:56:54 +04:00
if ( chan - > conn ) {
2012-05-07 10:07:26 +04:00
sec . level = chan - > conn - > hcon - > sec_level ;
2011-02-04 07:52:55 +03:00
2012-10-05 17:56:54 +04:00
if ( sk - > sk_state = = BT_CONNECTED )
sec . key_size = chan - > conn - > hcon - > enc_key_size ;
} else {
sec . level = chan - > sec_level ;
}
2011-07-09 01:31:46 +04:00
2011-02-04 07:52:55 +03:00
len = min_t ( unsigned int , len , sizeof ( sec ) ) ;
if ( copy_to_user ( optval , ( char * ) & sec , len ) )
err = - EFAULT ;
break ;
case BT_DEFER_SETUP :
if ( sk - > sk_state ! = BT_BOUND & & sk - > sk_state ! = BT_LISTEN ) {
err = - EINVAL ;
break ;
}
2012-05-16 19:17:10 +04:00
if ( put_user ( test_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ,
( u32 __user * ) optval ) )
2011-02-04 07:52:55 +03:00
err = - EFAULT ;
break ;
case BT_FLUSHABLE :
2011-10-11 15:04:31 +04:00
if ( put_user ( test_bit ( FLAG_FLUSHABLE , & chan - > flags ) ,
2012-10-06 13:07:01 +04:00
( u32 __user * ) optval ) )
2011-02-04 07:52:55 +03:00
err = - EFAULT ;
break ;
2011-05-24 05:06:04 +04:00
case BT_POWER :
if ( sk - > sk_type ! = SOCK_SEQPACKET & & sk - > sk_type ! = SOCK_STREAM
2012-10-06 13:07:01 +04:00
& & sk - > sk_type ! = SOCK_RAW ) {
2011-05-24 05:06:04 +04:00
err = - EINVAL ;
break ;
}
2011-10-11 15:04:33 +04:00
pwr . force_active = test_bit ( FLAG_FORCE_ACTIVE , & chan - > flags ) ;
2011-05-24 05:06:04 +04:00
len = min_t ( unsigned int , len , sizeof ( pwr ) ) ;
if ( copy_to_user ( optval , ( char * ) & pwr , len ) )
err = - EFAULT ;
break ;
2011-11-03 03:18:30 +04:00
case BT_CHANNEL_POLICY :
if ( put_user ( chan - > chan_policy , ( u32 __user * ) optval ) )
err = - EFAULT ;
break ;
2013-12-02 18:34:18 +04:00
case BT_SNDMTU :
if ( ! enable_lecoc ) {
err = - EPROTONOSUPPORT ;
break ;
}
if ( ! bdaddr_type_is_le ( chan - > src_type ) ) {
err = - EINVAL ;
break ;
}
if ( sk - > sk_state ! = BT_CONNECTED ) {
err = - ENOTCONN ;
break ;
}
if ( put_user ( chan - > omtu , ( u16 __user * ) optval ) )
err = - EFAULT ;
break ;
case BT_RCVMTU :
if ( ! enable_lecoc ) {
err = - EPROTONOSUPPORT ;
break ;
}
if ( ! bdaddr_type_is_le ( chan - > src_type ) ) {
err = - EINVAL ;
break ;
}
if ( put_user ( chan - > imtu , ( u16 __user * ) optval ) )
err = - EFAULT ;
break ;
2011-02-04 07:52:55 +03:00
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
return err ;
}
2012-06-01 00:01:34 +04:00
static bool l2cap_valid_mtu ( struct l2cap_chan * chan , u16 mtu )
{
switch ( chan - > scid ) {
2013-04-29 20:35:35 +04:00
case L2CAP_CID_ATT :
2012-06-01 00:01:35 +04:00
if ( mtu < L2CAP_LE_MIN_MTU )
2012-06-01 00:01:34 +04:00
return false ;
break ;
default :
if ( mtu < L2CAP_DEFAULT_MIN_MTU )
return false ;
}
return true ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_setsockopt_old ( struct socket * sock , int optname ,
char __user * optval , unsigned int optlen )
2011-02-04 07:48:48 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-13 01:15:09 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:48:48 +03:00
struct l2cap_options opts ;
int len , err = 0 ;
u32 opt ;
BT_DBG ( " sk %p " , sk ) ;
lock_sock ( sk ) ;
switch ( optname ) {
case L2CAP_OPTIONS :
2013-12-02 18:02:03 +04:00
if ( bdaddr_type_is_le ( chan - > src_type ) ) {
err = - EINVAL ;
break ;
}
2011-02-04 07:48:48 +03:00
if ( sk - > sk_state = = BT_CONNECTED ) {
err = - EINVAL ;
break ;
}
2011-04-14 00:20:49 +04:00
opts . imtu = chan - > imtu ;
opts . omtu = chan - > omtu ;
opts . flush_to = chan - > flush_to ;
opts . mode = chan - > mode ;
2011-04-13 22:57:03 +04:00
opts . fcs = chan - > fcs ;
opts . max_tx = chan - > max_tx ;
2011-10-11 14:37:42 +04:00
opts . txwin_size = chan - > tx_win ;
2011-02-04 07:48:48 +03:00
len = min_t ( unsigned int , sizeof ( opts ) , optlen ) ;
if ( copy_from_user ( ( char * ) & opts , optval , len ) ) {
err = - EFAULT ;
break ;
}
2011-10-11 14:37:42 +04:00
if ( opts . txwin_size > L2CAP_DEFAULT_EXT_WINDOW ) {
2011-02-04 07:48:48 +03:00
err = - EINVAL ;
break ;
}
2012-06-01 00:01:34 +04:00
if ( ! l2cap_valid_mtu ( chan , opts . imtu ) ) {
err = - EINVAL ;
break ;
}
2011-04-14 00:20:49 +04:00
chan - > mode = opts . mode ;
switch ( chan - > mode ) {
2013-05-17 13:49:23 +04:00
case L2CAP_MODE_LE_FLOWCTL :
break ;
2011-02-04 07:48:48 +03:00
case L2CAP_MODE_BASIC :
2011-06-11 00:02:12 +04:00
clear_bit ( CONF_STATE2_DEVICE , & chan - > conf_state ) ;
2011-02-04 07:48:48 +03:00
break ;
case L2CAP_MODE_ERTM :
case L2CAP_MODE_STREAMING :
if ( ! disable_ertm )
break ;
/* fall through */
default :
err = - EINVAL ;
break ;
}
2011-04-14 00:20:49 +04:00
chan - > imtu = opts . imtu ;
chan - > omtu = opts . omtu ;
2011-04-13 22:57:03 +04:00
chan - > fcs = opts . fcs ;
chan - > max_tx = opts . max_tx ;
2011-10-11 14:37:42 +04:00
chan - > tx_win = opts . txwin_size ;
2012-10-10 18:38:26 +04:00
chan - > flush_to = opts . flush_to ;
2011-02-04 07:48:48 +03:00
break ;
case L2CAP_LM :
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
2014-01-16 10:37:40 +04:00
if ( opt & L2CAP_LM_FIPS ) {
err = - EINVAL ;
break ;
}
2011-02-04 07:48:48 +03:00
if ( opt & L2CAP_LM_AUTH )
2011-04-13 01:31:57 +04:00
chan - > sec_level = BT_SECURITY_LOW ;
2011-02-04 07:48:48 +03:00
if ( opt & L2CAP_LM_ENCRYPT )
2011-04-13 01:31:57 +04:00
chan - > sec_level = BT_SECURITY_MEDIUM ;
2011-02-04 07:48:48 +03:00
if ( opt & L2CAP_LM_SECURE )
2011-04-13 01:31:57 +04:00
chan - > sec_level = BT_SECURITY_HIGH ;
2011-02-04 07:48:48 +03:00
2011-10-11 15:04:34 +04:00
if ( opt & L2CAP_LM_MASTER )
set_bit ( FLAG_ROLE_SWITCH , & chan - > flags ) ;
else
clear_bit ( FLAG_ROLE_SWITCH , & chan - > flags ) ;
2011-10-11 15:04:32 +04:00
if ( opt & L2CAP_LM_RELIABLE )
set_bit ( FLAG_FORCE_RELIABLE , & chan - > flags ) ;
else
clear_bit ( FLAG_FORCE_RELIABLE , & chan - > flags ) ;
2011-02-04 07:48:48 +03:00
break ;
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
return err ;
}
2012-10-06 13:07:01 +04:00
static int l2cap_sock_setsockopt ( struct socket * sock , int level , int optname ,
char __user * optval , unsigned int optlen )
2011-02-04 07:48:48 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-13 01:31:57 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 07:48:48 +03:00
struct bt_security sec ;
2011-05-24 05:06:04 +04:00
struct bt_power pwr ;
2011-01-27 03:42:57 +03:00
struct l2cap_conn * conn ;
2011-02-04 07:48:48 +03:00
int len , err = 0 ;
u32 opt ;
BT_DBG ( " sk %p " , sk ) ;
if ( level = = SOL_L2CAP )
return l2cap_sock_setsockopt_old ( sock , optname , optval , optlen ) ;
if ( level ! = SOL_BLUETOOTH )
return - ENOPROTOOPT ;
lock_sock ( sk ) ;
switch ( optname ) {
case BT_SECURITY :
2011-05-03 00:13:55 +04:00
if ( chan - > chan_type ! = L2CAP_CHAN_CONN_ORIENTED & &
2012-10-06 13:07:01 +04:00
chan - > chan_type ! = L2CAP_CHAN_RAW ) {
2011-02-04 07:48:48 +03:00
err = - EINVAL ;
break ;
}
sec . level = BT_SECURITY_LOW ;
len = min_t ( unsigned int , sizeof ( sec ) , optlen ) ;
if ( copy_from_user ( ( char * ) & sec , optval , len ) ) {
err = - EFAULT ;
break ;
}
if ( sec . level < BT_SECURITY_LOW | |
2012-10-06 13:07:01 +04:00
sec . level > BT_SECURITY_HIGH ) {
2011-02-04 07:48:48 +03:00
err = - EINVAL ;
break ;
}
2011-04-13 01:31:57 +04:00
chan - > sec_level = sec . level ;
2011-01-27 03:42:57 +03:00
2011-11-06 01:58:31 +04:00
if ( ! chan - > conn )
break ;
2011-01-27 03:42:57 +03:00
conn = chan - > conn ;
2011-11-06 01:58:31 +04:00
/*change security for LE channels */
2013-04-29 20:35:35 +04:00
if ( chan - > scid = = L2CAP_CID_ATT ) {
2011-01-27 03:42:57 +03:00
if ( ! conn - > hcon - > out ) {
err = - EINVAL ;
break ;
}
2012-08-24 04:32:43 +04:00
if ( smp_conn_security ( conn - > hcon , sec . level ) )
2011-01-27 03:42:57 +03:00
break ;
sk - > sk_state = BT_CONFIG ;
2011-12-28 19:54:17 +04:00
chan - > state = BT_CONFIG ;
2011-11-06 01:58:31 +04:00
2012-05-13 10:20:07 +04:00
/* or for ACL link */
} else if ( ( sk - > sk_state = = BT_CONNECT2 & &
2012-10-06 13:07:01 +04:00
test_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ) | |
2012-05-13 10:20:07 +04:00
sk - > sk_state = = BT_CONNECTED ) {
if ( ! l2cap_chan_check_security ( chan ) )
2012-05-16 19:17:10 +04:00
set_bit ( BT_SK_SUSPEND , & bt_sk ( sk ) - > flags ) ;
2012-05-13 10:20:07 +04:00
else
sk - > sk_state_change ( sk ) ;
2011-11-06 01:58:31 +04:00
} else {
err = - EINVAL ;
2011-01-27 03:42:57 +03:00
}
2011-02-04 07:48:48 +03:00
break ;
case BT_DEFER_SETUP :
if ( sk - > sk_state ! = BT_BOUND & & sk - > sk_state ! = BT_LISTEN ) {
err = - EINVAL ;
break ;
}
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
2013-10-14 13:45:34 +04:00
if ( opt ) {
2012-05-16 19:17:10 +04:00
set_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ;
2013-10-14 13:45:34 +04:00
set_bit ( FLAG_DEFER_SETUP , & chan - > flags ) ;
} else {
2012-05-16 19:17:10 +04:00
clear_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ;
2013-10-14 13:45:34 +04:00
clear_bit ( FLAG_DEFER_SETUP , & chan - > flags ) ;
}
2011-02-04 07:48:48 +03:00
break ;
case BT_FLUSHABLE :
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
if ( opt > BT_FLUSHABLE_ON ) {
err = - EINVAL ;
break ;
}
if ( opt = = BT_FLUSHABLE_OFF ) {
2013-10-07 20:19:16 +04:00
conn = chan - > conn ;
2011-03-31 05:57:33 +04:00
/* proceed further only when we have l2cap_conn and
2011-02-04 07:48:48 +03:00
No Flush support in the LM */
if ( ! conn | | ! lmp_no_flush_capable ( conn - > hcon - > hdev ) ) {
err = - EINVAL ;
break ;
}
}
2011-10-11 15:04:31 +04:00
if ( opt )
set_bit ( FLAG_FLUSHABLE , & chan - > flags ) ;
else
clear_bit ( FLAG_FLUSHABLE , & chan - > flags ) ;
2011-02-04 07:48:48 +03:00
break ;
2011-05-24 05:06:04 +04:00
case BT_POWER :
if ( chan - > chan_type ! = L2CAP_CHAN_CONN_ORIENTED & &
2012-10-06 13:07:01 +04:00
chan - > chan_type ! = L2CAP_CHAN_RAW ) {
2011-05-24 05:06:04 +04:00
err = - EINVAL ;
break ;
}
pwr . force_active = BT_POWER_FORCE_ACTIVE_ON ;
len = min_t ( unsigned int , sizeof ( pwr ) , optlen ) ;
if ( copy_from_user ( ( char * ) & pwr , optval , len ) ) {
err = - EFAULT ;
break ;
}
2011-10-11 15:04:33 +04:00
if ( pwr . force_active )
set_bit ( FLAG_FORCE_ACTIVE , & chan - > flags ) ;
else
clear_bit ( FLAG_FORCE_ACTIVE , & chan - > flags ) ;
2011-05-24 05:06:04 +04:00
break ;
2011-11-03 03:18:30 +04:00
case BT_CHANNEL_POLICY :
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
if ( opt > BT_CHANNEL_POLICY_AMP_PREFERRED ) {
err = - EINVAL ;
break ;
}
if ( chan - > mode ! = L2CAP_MODE_ERTM & &
2012-10-06 13:07:01 +04:00
chan - > mode ! = L2CAP_MODE_STREAMING ) {
2011-11-03 03:18:30 +04:00
err = - EOPNOTSUPP ;
break ;
}
chan - > chan_policy = ( u8 ) opt ;
2012-10-24 02:24:23 +04:00
if ( sk - > sk_state = = BT_CONNECTED & &
chan - > move_role = = L2CAP_MOVE_ROLE_NONE )
l2cap_move_start ( chan ) ;
2011-05-24 05:06:04 +04:00
break ;
2013-12-02 18:34:18 +04:00
case BT_SNDMTU :
if ( ! enable_lecoc ) {
err = - EPROTONOSUPPORT ;
break ;
}
if ( ! bdaddr_type_is_le ( chan - > src_type ) ) {
err = - EINVAL ;
break ;
}
/* Setting is not supported as it's the remote side that
* decides this .
*/
err = - EPERM ;
break ;
case BT_RCVMTU :
if ( ! enable_lecoc ) {
err = - EPROTONOSUPPORT ;
break ;
}
if ( ! bdaddr_type_is_le ( chan - > src_type ) ) {
err = - EINVAL ;
break ;
}
if ( sk - > sk_state = = BT_CONNECTED ) {
err = - EISCONN ;
break ;
}
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
chan - > imtu = opt ;
break ;
2011-02-04 07:48:48 +03:00
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
return err ;
}
2011-02-04 08:20:52 +03:00
2012-10-06 13:07:01 +04:00
static int l2cap_sock_sendmsg ( struct kiocb * iocb , struct socket * sock ,
struct msghdr * msg , size_t len )
2011-02-04 08:20:52 +03:00
{
struct sock * sk = sock - > sk ;
2011-04-14 00:20:49 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 08:20:52 +03:00
int err ;
BT_DBG ( " sock %p, sk %p " , sock , sk ) ;
err = sock_error ( sk ) ;
if ( err )
return err ;
if ( msg - > msg_flags & MSG_OOB )
return - EOPNOTSUPP ;
2012-05-05 01:20:31 +04:00
if ( sk - > sk_state ! = BT_CONNECTED )
2011-04-29 01:50:17 +04:00
return - ENOTCONN ;
2011-02-04 08:20:52 +03:00
2013-09-16 14:05:19 +04:00
lock_sock ( sk ) ;
err = bt_sock_wait_ready ( sk , msg - > msg_flags ) ;
release_sock ( sk ) ;
if ( err )
return err ;
2012-05-05 01:20:31 +04:00
l2cap_chan_lock ( chan ) ;
2011-11-01 12:58:57 +04:00
err = l2cap_chan_send ( chan , msg , len , sk - > sk_priority ) ;
2012-05-05 01:20:31 +04:00
l2cap_chan_unlock ( chan ) ;
2011-02-04 08:20:52 +03:00
return err ;
}
2011-02-04 07:48:48 +03:00
2012-10-06 13:07:01 +04:00
static int l2cap_sock_recvmsg ( struct kiocb * iocb , struct socket * sock ,
struct msghdr * msg , size_t len , int flags )
2011-02-04 08:02:31 +03:00
{
struct sock * sk = sock - > sk ;
2011-07-07 20:39:02 +04:00
struct l2cap_pinfo * pi = l2cap_pi ( sk ) ;
int err ;
2011-02-04 08:02:31 +03:00
lock_sock ( sk ) ;
2012-05-16 19:17:10 +04:00
if ( sk - > sk_state = = BT_CONNECT2 & & test_bit ( BT_SK_DEFER_SETUP ,
& bt_sk ( sk ) - > flags ) ) {
2013-05-17 13:49:23 +04:00
if ( bdaddr_type_is_le ( pi - > chan - > src_type ) ) {
sk - > sk_state = BT_CONNECTED ;
pi - > chan - > state = BT_CONNECTED ;
__l2cap_le_connect_rsp_defer ( pi - > chan ) ;
} else {
sk - > sk_state = BT_CONFIG ;
pi - > chan - > state = BT_CONFIG ;
__l2cap_connect_rsp_defer ( pi - > chan ) ;
}
2011-04-14 03:23:55 +04:00
2013-09-25 14:26:05 +04:00
err = 0 ;
goto done ;
2011-02-04 08:02:31 +03:00
}
release_sock ( sk ) ;
if ( sock - > type = = SOCK_STREAM )
2011-07-07 20:39:02 +04:00
err = bt_sock_stream_recvmsg ( iocb , sock , msg , len , flags ) ;
else
err = bt_sock_recvmsg ( iocb , sock , msg , len , flags ) ;
if ( pi - > chan - > mode ! = L2CAP_MODE_ERTM )
return err ;
/* Attempt to put pending rx data in the socket buffer */
lock_sock ( sk ) ;
if ( ! test_bit ( CONN_LOCAL_BUSY , & pi - > chan - > conn_state ) )
goto done ;
if ( pi - > rx_busy_skb ) {
if ( ! sock_queue_rcv_skb ( sk , pi - > rx_busy_skb ) )
pi - > rx_busy_skb = NULL ;
else
goto done ;
}
/* Restore data flow when half of the receive buffer is
* available . This avoids resending large numbers of
* frames .
*/
if ( atomic_read ( & sk - > sk_rmem_alloc ) < = sk - > sk_rcvbuf > > 1 )
l2cap_chan_busy ( pi - > chan , 0 ) ;
2011-02-04 08:02:31 +03:00
2011-07-07 20:39:02 +04:00
done :
release_sock ( sk ) ;
return err ;
2011-02-04 08:02:31 +03:00
}
2011-02-04 08:26:01 +03:00
/* Kill socket (only if zapped and orphan)
* Must be called on unlocked socket .
*/
2011-05-17 01:23:24 +04:00
static void l2cap_sock_kill ( struct sock * sk )
2011-02-04 08:26:01 +03:00
{
if ( ! sock_flag ( sk , SOCK_ZAPPED ) | | sk - > sk_socket )
return ;
2012-02-17 13:40:56 +04:00
BT_DBG ( " sk %p state %s " , sk , state_to_string ( sk - > sk_state ) ) ;
2011-02-04 08:26:01 +03:00
/* Kill poor orphan */
2011-04-25 22:10:41 +04:00
2012-07-13 16:47:55 +04:00
l2cap_chan_put ( l2cap_pi ( sk ) - > chan ) ;
2011-02-04 08:26:01 +03:00
sock_set_flag ( sk , SOCK_DEAD ) ;
sock_put ( sk ) ;
}
2013-10-16 02:24:49 +04:00
static int __l2cap_wait_ack ( struct sock * sk )
{
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
DECLARE_WAITQUEUE ( wait , current ) ;
int err = 0 ;
int timeo = HZ / 5 ;
add_wait_queue ( sk_sleep ( sk ) , & wait ) ;
set_current_state ( TASK_INTERRUPTIBLE ) ;
while ( chan - > unacked_frames > 0 & & chan - > conn ) {
if ( ! timeo )
timeo = HZ / 5 ;
if ( signal_pending ( current ) ) {
err = sock_intr_errno ( timeo ) ;
break ;
}
release_sock ( sk ) ;
timeo = schedule_timeout ( timeo ) ;
lock_sock ( sk ) ;
set_current_state ( TASK_INTERRUPTIBLE ) ;
err = sock_error ( sk ) ;
if ( err )
break ;
}
set_current_state ( TASK_RUNNING ) ;
remove_wait_queue ( sk_sleep ( sk ) , & wait ) ;
return err ;
}
2011-02-04 08:08:36 +03:00
static int l2cap_sock_shutdown ( struct socket * sock , int how )
{
struct sock * sk = sock - > sk ;
2012-02-14 17:12:57 +04:00
struct l2cap_chan * chan ;
2012-02-21 14:54:55 +04:00
struct l2cap_conn * conn ;
2011-02-04 08:08:36 +03:00
int err = 0 ;
BT_DBG ( " sock %p, sk %p " , sock , sk ) ;
if ( ! sk )
return 0 ;
2012-02-14 17:12:57 +04:00
chan = l2cap_pi ( sk ) - > chan ;
2012-02-21 14:54:55 +04:00
conn = chan - > conn ;
if ( conn )
mutex_lock ( & conn - > chan_lock ) ;
2012-02-14 17:12:57 +04:00
2012-02-22 19:11:56 +04:00
l2cap_chan_lock ( chan ) ;
2011-02-04 08:08:36 +03:00
lock_sock ( sk ) ;
2012-02-22 19:11:56 +04:00
2011-02-04 08:08:36 +03:00
if ( ! sk - > sk_shutdown ) {
2011-04-14 00:20:49 +04:00
if ( chan - > mode = = L2CAP_MODE_ERTM )
2011-02-04 08:08:36 +03:00
err = __l2cap_wait_ack ( sk ) ;
sk - > sk_shutdown = SHUTDOWN_MASK ;
2012-02-21 14:54:55 +04:00
2012-02-22 19:11:56 +04:00
release_sock ( sk ) ;
2011-05-05 02:42:50 +04:00
l2cap_chan_close ( chan , 0 ) ;
2012-02-22 19:11:56 +04:00
lock_sock ( sk ) ;
2011-02-04 08:08:36 +03:00
if ( sock_flag ( sk , SOCK_LINGER ) & & sk - > sk_lingertime )
err = bt_sock_wait_state ( sk , BT_CLOSED ,
2012-10-06 13:07:01 +04:00
sk - > sk_lingertime ) ;
2011-02-04 08:08:36 +03:00
}
if ( ! err & & sk - > sk_err )
err = - sk - > sk_err ;
release_sock ( sk ) ;
2012-02-22 19:11:56 +04:00
l2cap_chan_unlock ( chan ) ;
2012-02-21 14:54:55 +04:00
if ( conn )
mutex_unlock ( & conn - > chan_lock ) ;
2011-02-04 08:08:36 +03:00
return err ;
}
2011-02-04 07:36:42 +03:00
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 ;
2012-07-25 20:29:25 +04:00
bt_sock_unlink ( & l2cap_sk_list , sk ) ;
2011-02-04 07:36:42 +03:00
err = l2cap_sock_shutdown ( sock , 2 ) ;
sock_orphan ( sk ) ;
l2cap_sock_kill ( sk ) ;
return err ;
}
2012-05-28 05:27:52 +04:00
static void l2cap_sock_cleanup_listen ( struct sock * parent )
{
struct sock * sk ;
BT_DBG ( " parent %p " , parent ) ;
/* Close not yet accepted channels */
while ( ( sk = bt_accept_dequeue ( parent , NULL ) ) ) {
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
l2cap_chan_lock ( chan ) ;
__clear_chan_timer ( chan ) ;
l2cap_chan_close ( chan , ECONNRESET ) ;
l2cap_chan_unlock ( chan ) ;
l2cap_sock_kill ( sk ) ;
}
}
2012-05-28 05:27:51 +04:00
static struct l2cap_chan * l2cap_sock_new_connection_cb ( struct l2cap_chan * chan )
2011-05-17 00:24:37 +04:00
{
2012-05-28 05:27:51 +04:00
struct sock * sk , * parent = chan - > data ;
2011-05-17 00:24:37 +04:00
2013-10-21 20:21:41 +04:00
lock_sock ( parent ) ;
2012-05-28 05:27:55 +04:00
/* Check for backlog size */
if ( sk_acceptq_is_full ( parent ) ) {
BT_DBG ( " backlog full %d " , parent - > sk_ack_backlog ) ;
return NULL ;
}
2011-05-17 00:24:37 +04:00
sk = l2cap_sock_alloc ( sock_net ( parent ) , NULL , BTPROTO_L2CAP ,
2012-10-06 13:07:01 +04:00
GFP_ATOMIC ) ;
2011-05-17 00:24:37 +04:00
if ( ! sk )
return NULL ;
2012-01-22 02:28:34 +04:00
bt_sock_reclassify_lock ( sk , BTPROTO_L2CAP ) ;
2011-05-17 00:24:37 +04:00
l2cap_sock_init ( sk , parent ) ;
2012-10-12 15:35:23 +04:00
bt_accept_enqueue ( parent , sk ) ;
2013-10-21 20:21:41 +04:00
release_sock ( parent ) ;
2011-05-17 00:24:37 +04:00
return l2cap_pi ( sk ) - > chan ;
}
2012-05-28 05:27:51 +04:00
static int l2cap_sock_recv_cb ( struct l2cap_chan * chan , struct sk_buff * skb )
2011-05-17 00:57:22 +04:00
{
2012-05-28 05:27:51 +04:00
struct sock * sk = chan - > data ;
2013-10-13 22:36:07 +04:00
int err ;
2011-07-07 20:39:02 +04:00
2012-02-22 19:11:56 +04:00
lock_sock ( sk ) ;
2013-10-13 22:36:07 +04:00
if ( l2cap_pi ( sk ) - > rx_busy_skb ) {
2012-02-22 19:11:56 +04:00
err = - ENOMEM ;
goto done ;
}
2011-07-07 20:39:02 +04:00
err = sock_queue_rcv_skb ( sk , skb ) ;
/* For ERTM, handle one skb that doesn't fit into the recv
* buffer . This is important to do because the data frames
* have already been acked , so the skb cannot be discarded .
*
* Notify the l2cap core that the buffer is full , so the
* LOCAL_BUSY state is entered and no more frames are
* acked and reassembled until there is buffer space
* available .
*/
2013-10-13 22:36:07 +04:00
if ( err < 0 & & chan - > mode = = L2CAP_MODE_ERTM ) {
l2cap_pi ( sk ) - > rx_busy_skb = skb ;
l2cap_chan_busy ( chan , 1 ) ;
2011-07-07 20:39:02 +04:00
err = 0 ;
}
2011-05-17 00:57:22 +04:00
2012-02-22 19:11:56 +04:00
done :
release_sock ( sk ) ;
2011-07-07 20:39:02 +04:00
return err ;
2011-05-17 00:57:22 +04:00
}
2012-05-28 05:27:51 +04:00
static void l2cap_sock_close_cb ( struct l2cap_chan * chan )
2011-05-17 01:23:24 +04:00
{
2012-05-28 05:27:51 +04:00
struct sock * sk = chan - > data ;
2011-05-17 01:23:24 +04:00
l2cap_sock_kill ( sk ) ;
}
2012-05-28 05:27:52 +04:00
static void l2cap_sock_teardown_cb ( struct l2cap_chan * chan , int err )
{
struct sock * sk = chan - > data ;
struct sock * parent ;
lock_sock ( sk ) ;
parent = bt_sk ( sk ) - > parent ;
sock_set_flag ( sk , SOCK_ZAPPED ) ;
switch ( chan - > state ) {
case BT_OPEN :
case BT_BOUND :
case BT_CLOSED :
break ;
case BT_LISTEN :
l2cap_sock_cleanup_listen ( sk ) ;
sk - > sk_state = BT_CLOSED ;
chan - > state = BT_CLOSED ;
break ;
default :
sk - > sk_state = BT_CLOSED ;
chan - > state = BT_CLOSED ;
sk - > sk_err = err ;
if ( parent ) {
bt_accept_unlink ( sk ) ;
parent - > sk_data_ready ( parent , 0 ) ;
} else {
sk - > sk_state_change ( sk ) ;
}
break ;
}
release_sock ( sk ) ;
}
2013-10-16 02:24:45 +04:00
static void l2cap_sock_state_change_cb ( struct l2cap_chan * chan , int state ,
int err )
2011-06-03 07:19:47 +04:00
{
2012-05-28 05:27:51 +04:00
struct sock * sk = chan - > data ;
2011-06-03 07:19:47 +04:00
sk - > sk_state = state ;
2013-10-16 02:24:45 +04:00
if ( err )
sk - > sk_err = err ;
2011-06-03 07:19:47 +04:00
}
2012-01-20 16:08:03 +04:00
static struct sk_buff * l2cap_sock_alloc_skb_cb ( struct l2cap_chan * chan ,
2012-04-07 03:15:47 +04:00
unsigned long len , int nb )
2012-01-20 16:08:03 +04:00
{
2013-10-21 20:21:38 +04:00
struct sock * sk = chan - > data ;
2012-04-07 03:15:47 +04:00
struct sk_buff * skb ;
int err ;
2012-05-05 01:20:31 +04:00
l2cap_chan_unlock ( chan ) ;
2013-10-21 20:21:38 +04:00
skb = bt_skb_send_alloc ( sk , len , nb , & err ) ;
2012-05-05 01:20:31 +04:00
l2cap_chan_lock ( chan ) ;
2012-04-07 03:15:47 +04:00
if ( ! skb )
return ERR_PTR ( err ) ;
2012-01-20 16:08:03 +04:00
2013-10-22 00:22:24 +04:00
bt_cb ( skb ) - > chan = chan ;
2012-04-07 03:15:47 +04:00
return skb ;
2012-01-20 16:08:03 +04:00
}
2012-05-28 05:27:53 +04:00
static void l2cap_sock_ready_cb ( struct l2cap_chan * chan )
{
struct sock * sk = chan - > data ;
struct sock * parent ;
lock_sock ( sk ) ;
parent = bt_sk ( sk ) - > parent ;
BT_DBG ( " sk %p, parent %p " , sk , parent ) ;
sk - > sk_state = BT_CONNECTED ;
sk - > sk_state_change ( sk ) ;
if ( parent )
parent - > sk_data_ready ( parent , 0 ) ;
release_sock ( sk ) ;
}
2012-10-12 15:35:24 +04:00
static void l2cap_sock_defer_cb ( struct l2cap_chan * chan )
{
2013-10-21 20:21:39 +04:00
struct sock * parent , * sk = chan - > data ;
lock_sock ( sk ) ;
2012-10-12 15:35:24 +04:00
2013-10-21 20:21:39 +04:00
parent = bt_sk ( sk ) - > parent ;
2012-10-12 15:35:24 +04:00
if ( parent )
parent - > sk_data_ready ( parent , 0 ) ;
2013-10-21 20:21:39 +04:00
release_sock ( sk ) ;
2012-10-12 15:35:24 +04:00
}
2013-10-14 13:53:54 +04:00
static void l2cap_sock_resume_cb ( struct l2cap_chan * chan )
{
struct sock * sk = chan - > data ;
clear_bit ( BT_SK_SUSPEND , & bt_sk ( sk ) - > flags ) ;
sk - > sk_state_change ( sk ) ;
}
2013-10-16 02:24:48 +04:00
static void l2cap_sock_set_shutdown_cb ( struct l2cap_chan * chan )
{
struct sock * sk = chan - > data ;
lock_sock ( sk ) ;
sk - > sk_shutdown = SHUTDOWN_MASK ;
release_sock ( sk ) ;
}
2013-10-16 02:24:47 +04:00
static long l2cap_sock_get_sndtimeo_cb ( struct l2cap_chan * chan )
{
struct sock * sk = chan - > data ;
return sk - > sk_sndtimeo ;
}
2013-10-15 12:03:18 +04:00
static void l2cap_sock_suspend_cb ( struct l2cap_chan * chan )
{
struct sock * sk = chan - > data ;
set_bit ( BT_SK_SUSPEND , & bt_sk ( sk ) - > flags ) ;
sk - > sk_state_change ( sk ) ;
}
2011-05-17 00:24:37 +04:00
static struct l2cap_ops l2cap_chan_ops = {
. name = " L2CAP Socket Interface " ,
. new_connection = l2cap_sock_new_connection_cb ,
2011-05-17 00:57:22 +04:00
. recv = l2cap_sock_recv_cb ,
2011-05-17 01:23:24 +04:00
. close = l2cap_sock_close_cb ,
2012-05-28 05:27:52 +04:00
. teardown = l2cap_sock_teardown_cb ,
2011-06-03 07:19:47 +04:00
. state_change = l2cap_sock_state_change_cb ,
2012-05-28 05:27:53 +04:00
. ready = l2cap_sock_ready_cb ,
2012-10-12 15:35:24 +04:00
. defer = l2cap_sock_defer_cb ,
2013-10-14 13:53:54 +04:00
. resume = l2cap_sock_resume_cb ,
2013-10-15 12:03:18 +04:00
. suspend = l2cap_sock_suspend_cb ,
2013-10-16 02:24:48 +04:00
. set_shutdown = l2cap_sock_set_shutdown_cb ,
2013-10-16 02:24:47 +04:00
. get_sndtimeo = l2cap_sock_get_sndtimeo_cb ,
2012-01-20 16:08:03 +04:00
. alloc_skb = l2cap_sock_alloc_skb_cb ,
2011-05-17 00:24:37 +04:00
} ;
2011-02-04 01:50:35 +03:00
static void l2cap_sock_destruct ( struct sock * sk )
{
BT_DBG ( " sk %p " , sk ) ;
2012-10-09 00:48:32 +04:00
if ( l2cap_pi ( sk ) - > chan )
l2cap_chan_put ( l2cap_pi ( sk ) - > chan ) ;
2013-10-13 22:36:07 +04:00
2011-07-07 20:39:02 +04:00
if ( l2cap_pi ( sk ) - > rx_busy_skb ) {
kfree_skb ( l2cap_pi ( sk ) - > rx_busy_skb ) ;
l2cap_pi ( sk ) - > rx_busy_skb = NULL ;
}
2011-02-04 01:50:35 +03:00
skb_queue_purge ( & sk - > sk_receive_queue ) ;
skb_queue_purge ( & sk - > sk_write_queue ) ;
}
2013-10-13 23:55:29 +04:00
static void l2cap_skb_msg_name ( struct sk_buff * skb , void * msg_name ,
int * msg_namelen )
{
2014-01-18 01:53:15 +04:00
DECLARE_SOCKADDR ( struct sockaddr_l2 * , la , msg_name ) ;
2013-10-13 23:55:29 +04:00
memset ( la , 0 , sizeof ( struct sockaddr_l2 ) ) ;
la - > l2_family = AF_BLUETOOTH ;
la - > l2_psm = bt_cb ( skb ) - > psm ;
bacpy ( & la - > l2_bdaddr , & bt_cb ( skb ) - > bdaddr ) ;
* msg_namelen = sizeof ( struct sockaddr_l2 ) ;
}
2011-05-17 00:24:37 +04:00
static void l2cap_sock_init ( struct sock * sk , struct sock * parent )
2011-02-04 01:50:35 +03:00
{
2013-10-13 22:36:07 +04:00
struct l2cap_chan * chan = l2cap_pi ( sk ) - > chan ;
2011-02-04 01:50:35 +03:00
BT_DBG ( " sk %p " , sk ) ;
if ( parent ) {
2011-04-13 01:15:09 +04:00
struct l2cap_chan * pchan = l2cap_pi ( parent ) - > chan ;
2011-02-04 01:50:35 +03:00
sk - > sk_type = parent - > sk_type ;
2012-05-16 19:17:10 +04:00
bt_sk ( sk ) - > flags = bt_sk ( parent ) - > flags ;
2011-02-04 01:50:35 +03:00
2011-05-03 00:13:55 +04:00
chan - > chan_type = pchan - > chan_type ;
2011-04-14 00:20:49 +04:00
chan - > imtu = pchan - > imtu ;
chan - > omtu = pchan - > omtu ;
2011-04-13 01:15:09 +04:00
chan - > conf_state = pchan - > conf_state ;
2011-04-14 00:20:49 +04:00
chan - > mode = pchan - > mode ;
2011-04-13 22:57:03 +04:00
chan - > fcs = pchan - > fcs ;
chan - > max_tx = pchan - > max_tx ;
chan - > tx_win = pchan - > tx_win ;
2011-11-02 11:57:10 +04:00
chan - > tx_win_max = pchan - > tx_win_max ;
2011-04-13 01:31:57 +04:00
chan - > sec_level = pchan - > sec_level ;
2011-10-11 15:04:31 +04:00
chan - > flags = pchan - > flags ;
2013-05-17 14:09:05 +04:00
chan - > tx_credits = pchan - > tx_credits ;
chan - > rx_credits = pchan - > rx_credits ;
2011-10-07 13:40:59 +04:00
security_sk_clone ( parent , sk ) ;
2011-02-04 01:50:35 +03:00
} else {
2011-05-03 00:13:55 +04:00
switch ( sk - > sk_type ) {
case SOCK_RAW :
chan - > chan_type = L2CAP_CHAN_RAW ;
break ;
case SOCK_DGRAM :
chan - > chan_type = L2CAP_CHAN_CONN_LESS ;
2013-10-13 23:55:29 +04:00
bt_sk ( sk ) - > skb_msg_name = l2cap_skb_msg_name ;
2011-05-03 00:13:55 +04:00
break ;
case SOCK_SEQPACKET :
case SOCK_STREAM :
chan - > chan_type = L2CAP_CHAN_CONN_ORIENTED ;
break ;
}
2011-04-14 00:20:49 +04:00
chan - > imtu = L2CAP_DEFAULT_MTU ;
chan - > omtu = 0 ;
2011-02-04 01:50:35 +03:00
if ( ! disable_ertm & & sk - > sk_type = = SOCK_STREAM ) {
2011-04-14 00:20:49 +04:00
chan - > mode = L2CAP_MODE_ERTM ;
2011-06-11 00:02:12 +04:00
set_bit ( CONF_STATE2_DEVICE , & chan - > conf_state ) ;
2011-02-04 01:50:35 +03:00
} else {
2011-04-14 00:20:49 +04:00
chan - > mode = L2CAP_MODE_BASIC ;
2011-02-04 01:50:35 +03:00
}
2012-03-28 17:31:25 +04:00
l2cap_chan_set_defaults ( chan ) ;
2011-02-04 01:50:35 +03:00
}
/* Default config options */
2011-04-14 00:20:49 +04:00
chan - > flush_to = L2CAP_DEFAULT_FLUSH_TO ;
2011-05-17 00:24:37 +04:00
chan - > data = sk ;
chan - > ops = & l2cap_chan_ops ;
2011-02-04 01:50:35 +03:00
}
static struct proto l2cap_proto = {
. name = " L2CAP " ,
. owner = THIS_MODULE ,
. obj_size = sizeof ( struct l2cap_pinfo )
} ;
2012-10-06 13:07:01 +04:00
static struct sock * l2cap_sock_alloc ( struct net * net , struct socket * sock ,
int proto , gfp_t prio )
2011-02-04 01:50:35 +03:00
{
struct sock * sk ;
2011-05-16 23:42:01 +04:00
struct l2cap_chan * chan ;
2011-02-04 01:50:35 +03:00
sk = sk_alloc ( net , PF_BLUETOOTH , prio , & l2cap_proto ) ;
if ( ! sk )
return NULL ;
sock_init_data ( sock , sk ) ;
INIT_LIST_HEAD ( & bt_sk ( sk ) - > accept_q ) ;
sk - > sk_destruct = l2cap_sock_destruct ;
2012-03-02 02:25:33 +04:00
sk - > sk_sndtimeo = L2CAP_CONN_TIMEOUT ;
2011-02-04 01:50:35 +03:00
sock_reset_flag ( sk , SOCK_ZAPPED ) ;
sk - > sk_protocol = proto ;
sk - > sk_state = BT_OPEN ;
2012-03-25 20:59:16 +04:00
chan = l2cap_chan_create ( ) ;
2011-05-16 23:42:01 +04:00
if ( ! chan ) {
2012-07-19 11:24:04 +04:00
sk_free ( sk ) ;
2011-05-16 23:42:01 +04:00
return NULL ;
}
2012-04-28 03:50:50 +04:00
l2cap_chan_hold ( chan ) ;
2011-05-16 23:42:01 +04:00
l2cap_pi ( sk ) - > chan = chan ;
2011-02-04 01:50:35 +03:00
return sk ;
}
static int l2cap_sock_create ( struct net * net , struct socket * sock , int protocol ,
int kern )
{
struct sock * sk ;
BT_DBG ( " sock %p " , sock ) ;
sock - > state = SS_UNCONNECTED ;
if ( sock - > type ! = SOCK_SEQPACKET & & sock - > type ! = SOCK_STREAM & &
2012-10-06 13:07:01 +04:00
sock - > type ! = SOCK_DGRAM & & sock - > type ! = SOCK_RAW )
2011-02-04 01:50:35 +03:00
return - ESOCKTNOSUPPORT ;
if ( sock - > type = = SOCK_RAW & & ! kern & & ! capable ( CAP_NET_RAW ) )
return - EPERM ;
sock - > ops = & l2cap_sock_ops ;
sk = l2cap_sock_alloc ( net , sock , protocol , GFP_ATOMIC ) ;
if ( ! sk )
return - ENOMEM ;
l2cap_sock_init ( sk , NULL ) ;
2012-07-25 20:29:25 +04:00
bt_sock_link ( & l2cap_sk_list , sk ) ;
2011-02-04 01:50:35 +03:00
return 0 ;
}
2011-04-28 01:40:39 +04:00
static const struct proto_ops l2cap_sock_ops = {
2011-02-04 07:33:56 +03:00
. family = PF_BLUETOOTH ,
. owner = THIS_MODULE ,
. release = l2cap_sock_release ,
. bind = l2cap_sock_bind ,
. connect = l2cap_sock_connect ,
. listen = l2cap_sock_listen ,
. accept = l2cap_sock_accept ,
. getname = l2cap_sock_getname ,
. sendmsg = l2cap_sock_sendmsg ,
. recvmsg = l2cap_sock_recvmsg ,
. poll = bt_sock_poll ,
. ioctl = bt_sock_ioctl ,
. mmap = sock_no_mmap ,
. socketpair = sock_no_socketpair ,
. shutdown = l2cap_sock_shutdown ,
. setsockopt = l2cap_sock_setsockopt ,
. getsockopt = l2cap_sock_getsockopt
} ;
2011-02-04 01:50:35 +03:00
static const struct net_proto_family l2cap_sock_family_ops = {
. family = PF_BLUETOOTH ,
. owner = THIS_MODULE ,
. create = l2cap_sock_create ,
} ;
int __init l2cap_init_sockets ( void )
{
2011-02-18 01:16:55 +03:00
int err ;
2011-02-04 01:50:35 +03:00
2011-02-18 01:16:55 +03:00
err = proto_register ( & l2cap_proto , 0 ) ;
if ( err < 0 )
return err ;
2011-02-04 01:50:35 +03:00
2011-02-18 01:16:55 +03:00
err = bt_sock_register ( BTPROTO_L2CAP , & l2cap_sock_family_ops ) ;
2012-07-25 20:29:25 +04:00
if ( err < 0 ) {
BT_ERR ( " L2CAP socket registration failed " ) ;
2011-02-18 01:16:55 +03:00
goto error ;
2012-07-25 20:29:25 +04:00
}
2013-04-05 03:14:33 +04:00
err = bt_procfs_init ( & init_net , " l2cap " , & l2cap_sk_list ,
2012-10-06 13:07:01 +04:00
NULL ) ;
2012-07-25 20:29:25 +04:00
if ( err < 0 ) {
BT_ERR ( " Failed to create L2CAP proc file " ) ;
bt_sock_unregister ( BTPROTO_L2CAP ) ;
goto error ;
}
2011-02-04 01:50:35 +03:00
2011-02-18 01:16:55 +03:00
BT_INFO ( " L2CAP socket layer initialized " ) ;
2011-02-04 01:50:35 +03:00
2011-02-18 01:16:55 +03:00
return 0 ;
2011-02-04 01:50:35 +03:00
error :
2011-02-18 01:16:55 +03:00
proto_unregister ( & l2cap_proto ) ;
return err ;
2011-02-04 01:50:35 +03:00
}
void l2cap_cleanup_sockets ( void )
{
2012-07-25 20:29:25 +04:00
bt_procfs_cleanup ( & init_net , " l2cap " ) ;
2013-02-24 22:36:51 +04:00
bt_sock_unregister ( BTPROTO_L2CAP ) ;
2011-02-18 01:16:55 +03:00
proto_unregister ( & l2cap_proto ) ;
2011-02-04 01:50:35 +03:00
}
2013-12-02 13:20:20 +04:00
module_param ( enable_lecoc , bool , 0644 ) ;
MODULE_PARM_DESC ( enable_lecoc , " Enable support for LE CoC " ) ;