2007-02-09 17:24:33 +03:00
/*
2005-04-17 02:20:36 +04:00
RFCOMM implementation for Linux Bluetooth stack ( BlueZ ) .
Copyright ( C ) 2002 Maxim Krasnyansky < maxk @ qualcomm . com >
Copyright ( C ) 2002 Marcel Holtmann < marcel @ holtmann . org >
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
2007-02-09 17:24:33 +03:00
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
2005-04-17 02:20:36 +04:00
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
2007-02-09 17:24:33 +03:00
ALL LIABILITY , INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS ,
COPYRIGHTS , TRADEMARKS OR OTHER RIGHTS , RELATING TO USE OF THIS
2005-04-17 02:20:36 +04:00
SOFTWARE IS DISCLAIMED .
*/
/*
* RFCOMM sockets .
*/
2012-05-23 11:04:22 +04:00
# include <linux/export.h>
2010-03-21 07:27:45 +03:00
# include <linux/debugfs.h>
2005-04-17 02:20:36 +04:00
# include <net/bluetooth/bluetooth.h>
# include <net/bluetooth/hci_core.h>
# include <net/bluetooth/l2cap.h>
# include <net/bluetooth/rfcomm.h>
2005-12-22 23:49:22 +03:00
static const struct proto_ops rfcomm_sock_ops ;
2005-04-17 02:20:36 +04:00
static struct bt_sock_list rfcomm_sk_list = {
2008-03-29 02:17:38 +03:00
. lock = __RW_LOCK_UNLOCKED ( rfcomm_sk_list . lock )
2005-04-17 02:20:36 +04:00
} ;
static void rfcomm_sock_close ( struct sock * sk ) ;
static void rfcomm_sock_kill ( struct sock * sk ) ;
/* ---- DLC callbacks ----
*
* called under rfcomm_dlc_lock ( )
*/
static void rfcomm_sk_data_ready ( struct rfcomm_dlc * d , struct sk_buff * skb )
{
struct sock * sk = d - > owner ;
if ( ! sk )
return ;
atomic_add ( skb - > len , & sk - > sk_rmem_alloc ) ;
skb_queue_tail ( & sk - > sk_receive_queue , skb ) ;
sk - > sk_data_ready ( sk , skb - > len ) ;
if ( atomic_read ( & sk - > sk_rmem_alloc ) > = sk - > sk_rcvbuf )
rfcomm_dlc_throttle ( d ) ;
}
static void rfcomm_sk_state_change ( struct rfcomm_dlc * d , int err )
{
struct sock * sk = d - > owner , * parent ;
2010-08-14 07:48:07 +04:00
unsigned long flags ;
2005-04-17 02:20:36 +04:00
if ( ! sk )
return ;
BT_DBG ( " dlc %p state %ld err %d " , d , d - > state , err ) ;
2010-08-14 07:48:07 +04:00
local_irq_save ( flags ) ;
2005-04-17 02:20:36 +04:00
bh_lock_sock ( sk ) ;
if ( err )
sk - > sk_err = err ;
sk - > sk_state = d - > state ;
parent = bt_sk ( sk ) - > parent ;
if ( parent ) {
if ( d - > state = = BT_CLOSED ) {
sock_set_flag ( sk , SOCK_ZAPPED ) ;
bt_accept_unlink ( sk ) ;
}
parent - > sk_data_ready ( parent , 0 ) ;
} else {
if ( d - > state = = BT_CONNECTED )
rfcomm_session_getaddr ( d - > session , & bt_sk ( sk ) - > src , NULL ) ;
sk - > sk_state_change ( sk ) ;
}
bh_unlock_sock ( sk ) ;
2010-08-14 07:48:07 +04:00
local_irq_restore ( flags ) ;
2005-04-17 02:20:36 +04:00
if ( parent & & sock_flag ( sk , SOCK_ZAPPED ) ) {
/* We have to drop DLC lock here, otherwise
* rfcomm_sock_destruct ( ) will dead lock . */
rfcomm_dlc_unlock ( d ) ;
rfcomm_sock_kill ( sk ) ;
rfcomm_dlc_lock ( d ) ;
}
}
/* ---- Socket functions ---- */
static struct sock * __rfcomm_get_sock_by_addr ( u8 channel , bdaddr_t * src )
{
struct sock * sk = NULL ;
struct hlist_node * node ;
sk_for_each ( sk , node , & rfcomm_sk_list . head ) {
2007-02-09 17:24:33 +03:00
if ( rfcomm_pi ( sk ) - > channel = = channel & &
2005-04-17 02:20:36 +04:00
! bacmp ( & bt_sk ( sk ) - > src , src ) )
break ;
}
return node ? sk : NULL ;
}
/* Find socket with channel and source bdaddr.
* Returns closest match .
*/
2010-11-01 21:43:53 +03:00
static struct sock * rfcomm_get_sock_by_channel ( int state , u8 channel , bdaddr_t * src )
2005-04-17 02:20:36 +04:00
{
struct sock * sk = NULL , * sk1 = NULL ;
struct hlist_node * node ;
2010-11-01 21:43:53 +03:00
read_lock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
sk_for_each ( sk , node , & rfcomm_sk_list . head ) {
if ( state & & sk - > sk_state ! = state )
continue ;
if ( rfcomm_pi ( sk ) - > channel = = channel ) {
/* Exact match. */
if ( ! bacmp ( & bt_sk ( sk ) - > src , src ) )
break ;
/* Closest match */
if ( ! bacmp ( & bt_sk ( sk ) - > src , BDADDR_ANY ) )
sk1 = sk ;
}
}
read_unlock ( & rfcomm_sk_list . lock ) ;
2010-11-01 21:43:53 +03:00
return node ? sk : sk1 ;
2005-04-17 02:20:36 +04:00
}
static void rfcomm_sock_destruct ( struct sock * sk )
{
struct rfcomm_dlc * d = rfcomm_pi ( sk ) - > dlc ;
BT_DBG ( " sk %p dlc %p " , sk , d ) ;
skb_queue_purge ( & sk - > sk_receive_queue ) ;
skb_queue_purge ( & sk - > sk_write_queue ) ;
rfcomm_dlc_lock ( d ) ;
rfcomm_pi ( sk ) - > dlc = NULL ;
/* Detach DLC if it's owned by this socket */
if ( d - > owner = = sk )
d - > owner = NULL ;
rfcomm_dlc_unlock ( d ) ;
rfcomm_dlc_put ( d ) ;
}
static void rfcomm_sock_cleanup_listen ( struct sock * parent )
{
struct sock * sk ;
BT_DBG ( " parent %p " , parent ) ;
/* Close not yet accepted dlcs */
while ( ( sk = bt_accept_dequeue ( parent , NULL ) ) ) {
rfcomm_sock_close ( sk ) ;
rfcomm_sock_kill ( sk ) ;
}
parent - > sk_state = BT_CLOSED ;
sock_set_flag ( parent , SOCK_ZAPPED ) ;
}
/* Kill socket (only if zapped and orphan)
* Must be called on unlocked socket .
*/
static void rfcomm_sock_kill ( struct sock * sk )
{
if ( ! sock_flag ( sk , SOCK_ZAPPED ) | | sk - > sk_socket )
return ;
BT_DBG ( " sk %p state %d refcnt %d " , sk , sk - > sk_state , atomic_read ( & sk - > sk_refcnt ) ) ;
/* Kill poor orphan */
bt_sock_unlink ( & rfcomm_sk_list , sk ) ;
sock_set_flag ( sk , SOCK_DEAD ) ;
sock_put ( sk ) ;
}
static void __rfcomm_sock_close ( struct sock * sk )
{
struct rfcomm_dlc * d = rfcomm_pi ( sk ) - > dlc ;
BT_DBG ( " sk %p state %d socket %p " , sk , sk - > sk_state , sk - > sk_socket ) ;
switch ( sk - > sk_state ) {
case BT_LISTEN :
rfcomm_sock_cleanup_listen ( sk ) ;
break ;
case BT_CONNECT :
case BT_CONNECT2 :
case BT_CONFIG :
case BT_CONNECTED :
rfcomm_dlc_close ( d , 0 ) ;
default :
sock_set_flag ( sk , SOCK_ZAPPED ) ;
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 ) ;
}
static void rfcomm_sock_init ( struct sock * sk , struct sock * parent )
{
struct rfcomm_pinfo * pi = rfcomm_pi ( sk ) ;
BT_DBG ( " sk %p " , sk ) ;
if ( parent ) {
sk - > sk_type = parent - > sk_type ;
2012-05-16 19:17:10 +04:00
pi - > dlc - > defer_setup = test_bit ( BT_SK_DEFER_SETUP ,
& bt_sk ( parent ) - > flags ) ;
2009-01-15 23:58:40 +03:00
pi - > sec_level = rfcomm_pi ( parent ) - > sec_level ;
pi - > role_switch = rfcomm_pi ( parent ) - > role_switch ;
2011-10-07 13:40:59 +04:00
security_sk_clone ( parent , sk ) ;
2005-04-17 02:20:36 +04:00
} else {
2009-01-15 23:56:48 +03:00
pi - > dlc - > defer_setup = 0 ;
2009-01-15 23:58:40 +03:00
pi - > sec_level = BT_SECURITY_LOW ;
pi - > role_switch = 0 ;
2005-04-17 02:20:36 +04:00
}
2009-01-15 23:58:40 +03:00
pi - > dlc - > sec_level = pi - > sec_level ;
pi - > dlc - > role_switch = pi - > role_switch ;
2005-04-17 02:20:36 +04:00
}
static struct proto rfcomm_proto = {
. name = " RFCOMM " ,
. owner = THIS_MODULE ,
. obj_size = sizeof ( struct rfcomm_pinfo )
} ;
2007-10-09 10:24:22 +04:00
static struct sock * rfcomm_sock_alloc ( struct net * net , struct socket * sock , int proto , gfp_t prio )
2005-04-17 02:20:36 +04:00
{
struct rfcomm_dlc * d ;
struct sock * sk ;
2007-11-01 10:39:31 +03:00
sk = sk_alloc ( net , PF_BLUETOOTH , prio , & rfcomm_proto ) ;
2005-04-17 02:20:36 +04:00
if ( ! sk )
return NULL ;
sock_init_data ( sock , sk ) ;
INIT_LIST_HEAD ( & bt_sk ( sk ) - > accept_q ) ;
d = rfcomm_dlc_alloc ( prio ) ;
if ( ! d ) {
sk_free ( sk ) ;
return NULL ;
}
d - > data_ready = rfcomm_sk_data_ready ;
d - > state_change = rfcomm_sk_state_change ;
rfcomm_pi ( sk ) - > dlc = d ;
d - > owner = sk ;
sk - > sk_destruct = rfcomm_sock_destruct ;
sk - > sk_sndtimeo = RFCOMM_CONN_TIMEOUT ;
2008-07-14 22:13:45 +04:00
sk - > sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10 ;
sk - > sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10 ;
2005-04-17 02:20:36 +04:00
sock_reset_flag ( sk , SOCK_ZAPPED ) ;
sk - > sk_protocol = proto ;
2008-07-14 22:13:45 +04:00
sk - > sk_state = BT_OPEN ;
2005-04-17 02:20:36 +04:00
bt_sock_link ( & rfcomm_sk_list , sk ) ;
BT_DBG ( " sk %p " , sk ) ;
return sk ;
}
2009-11-06 09:18:14 +03:00
static int rfcomm_sock_create ( struct net * net , struct socket * sock ,
int protocol , int kern )
2005-04-17 02:20:36 +04:00
{
struct sock * sk ;
BT_DBG ( " sock %p " , sock ) ;
sock - > state = SS_UNCONNECTED ;
if ( sock - > type ! = SOCK_STREAM & & sock - > type ! = SOCK_RAW )
return - ESOCKTNOSUPPORT ;
sock - > ops = & rfcomm_sock_ops ;
2007-10-09 10:24:22 +04:00
sk = rfcomm_sock_alloc ( net , sock , protocol , GFP_ATOMIC ) ;
2006-10-15 19:31:14 +04:00
if ( ! sk )
2005-04-17 02:20:36 +04:00
return - ENOMEM ;
rfcomm_sock_init ( sk , NULL ) ;
return 0 ;
}
static int rfcomm_sock_bind ( struct socket * sock , struct sockaddr * addr , int addr_len )
{
struct sockaddr_rc * sa = ( struct sockaddr_rc * ) addr ;
struct sock * sk = sock - > sk ;
int err = 0 ;
2012-09-25 13:49:43 +04:00
BT_DBG ( " sk %p %pMR " , sk , & sa - > rc_bdaddr ) ;
2005-04-17 02:20:36 +04:00
if ( ! addr | | addr - > sa_family ! = AF_BLUETOOTH )
return - EINVAL ;
lock_sock ( sk ) ;
if ( sk - > sk_state ! = BT_OPEN ) {
err = - EBADFD ;
goto done ;
}
2005-09-13 03:32:31 +04:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
goto done ;
}
2011-12-27 21:28:44 +04:00
write_lock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
if ( sa - > rc_channel & & __rfcomm_get_sock_by_addr ( sa - > rc_channel , & sa - > rc_bdaddr ) ) {
err = - EADDRINUSE ;
} else {
/* Save source address */
bacpy ( & bt_sk ( sk ) - > src , & sa - > rc_bdaddr ) ;
rfcomm_pi ( sk ) - > channel = sa - > rc_channel ;
sk - > sk_state = BT_BOUND ;
}
2011-12-27 21:28:44 +04:00
write_unlock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
done :
release_sock ( sk ) ;
return err ;
}
static int rfcomm_sock_connect ( struct socket * sock , struct sockaddr * addr , int alen , int flags )
{
struct sockaddr_rc * sa = ( struct sockaddr_rc * ) addr ;
struct sock * sk = sock - > sk ;
struct rfcomm_dlc * d = rfcomm_pi ( sk ) - > dlc ;
int err = 0 ;
BT_DBG ( " sk %p " , sk ) ;
2010-04-01 02:58:26 +04:00
if ( alen < sizeof ( struct sockaddr_rc ) | |
addr - > sa_family ! = AF_BLUETOOTH )
2005-04-17 02:20:36 +04:00
return - EINVAL ;
2005-09-13 03:32:31 +04:00
lock_sock ( sk ) ;
2005-04-17 02:20:36 +04:00
2005-09-13 03:32:31 +04:00
if ( sk - > sk_state ! = BT_OPEN & & sk - > sk_state ! = BT_BOUND ) {
err = - EBADFD ;
goto done ;
}
2005-04-17 02:20:36 +04:00
2005-09-13 03:32:31 +04:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
goto done ;
}
2005-04-17 02:20:36 +04:00
sk - > sk_state = BT_CONNECT ;
bacpy ( & bt_sk ( sk ) - > dst , & sa - > rc_bdaddr ) ;
rfcomm_pi ( sk ) - > channel = sa - > rc_channel ;
2009-01-15 23:58:40 +03:00
d - > sec_level = rfcomm_pi ( sk ) - > sec_level ;
d - > role_switch = rfcomm_pi ( sk ) - > role_switch ;
2008-07-14 22:13:45 +04:00
2005-04-17 02:20:36 +04:00
err = rfcomm_dlc_open ( d , & bt_sk ( sk ) - > src , & sa - > rc_bdaddr , sa - > rc_channel ) ;
if ( ! err )
err = bt_sock_wait_state ( sk , BT_CONNECTED ,
sock_sndtimeo ( sk , flags & O_NONBLOCK ) ) ;
2005-09-13 03:32:31 +04:00
done :
2005-04-17 02:20:36 +04:00
release_sock ( sk ) ;
return err ;
}
static int rfcomm_sock_listen ( struct socket * sock , int backlog )
{
struct sock * sk = sock - > sk ;
int err = 0 ;
BT_DBG ( " sk %p backlog %d " , sk , backlog ) ;
lock_sock ( sk ) ;
if ( sk - > sk_state ! = BT_BOUND ) {
err = - EBADFD ;
goto done ;
}
2005-09-13 03:32:31 +04:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
goto done ;
}
2005-04-17 02:20:36 +04:00
if ( ! rfcomm_pi ( sk ) - > channel ) {
bdaddr_t * src = & bt_sk ( sk ) - > src ;
u8 channel ;
err = - EINVAL ;
2011-12-27 21:28:44 +04:00
write_lock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
for ( channel = 1 ; channel < 31 ; channel + + )
if ( ! __rfcomm_get_sock_by_addr ( channel , src ) ) {
rfcomm_pi ( sk ) - > channel = channel ;
err = 0 ;
break ;
}
2011-12-27 21:28:44 +04:00
write_unlock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
goto done ;
}
sk - > sk_max_ack_backlog = backlog ;
sk - > sk_ack_backlog = 0 ;
sk - > sk_state = BT_LISTEN ;
done :
release_sock ( sk ) ;
return err ;
}
static int rfcomm_sock_accept ( struct socket * sock , struct socket * newsock , int flags )
{
DECLARE_WAITQUEUE ( wait , current ) ;
struct sock * sk = sock - > sk , * nsk ;
long timeo ;
int err = 0 ;
2012-11-21 05:25:54 +04:00
lock_sock_nested ( sk , SINGLE_DEPTH_NESTING ) ;
2005-04-17 02:20:36 +04:00
2005-09-13 03:32:31 +04:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
goto done ;
}
2005-04-17 02:20:36 +04:00
timeo = sock_rcvtimeo ( sk , flags & O_NONBLOCK ) ;
BT_DBG ( " sk %p timeo %ld " , sk , timeo ) ;
/* Wait for an incoming connection. (wake-one). */
2010-04-20 17:03:51 +04:00
add_wait_queue_exclusive ( sk_sleep ( sk ) , & wait ) ;
2011-07-24 08:10:41 +04:00
while ( 1 ) {
2005-04-17 02:20:36 +04:00
set_current_state ( TASK_INTERRUPTIBLE ) ;
2011-07-24 08:10:41 +04:00
if ( sk - > sk_state ! = BT_LISTEN ) {
err = - EBADFD ;
2005-04-17 02:20:36 +04:00
break ;
}
2011-07-24 08:10:41 +04:00
nsk = bt_accept_dequeue ( sk , newsock ) ;
if ( nsk )
break ;
2005-04-17 02:20:36 +04:00
2011-07-24 08:10:41 +04:00
if ( ! timeo ) {
err = - EAGAIN ;
2005-04-17 02:20:36 +04:00
break ;
}
if ( signal_pending ( current ) ) {
err = sock_intr_errno ( timeo ) ;
break ;
}
2011-07-24 08:10:41 +04:00
release_sock ( sk ) ;
timeo = schedule_timeout ( timeo ) ;
2012-11-21 05:25:54 +04:00
lock_sock_nested ( sk , SINGLE_DEPTH_NESTING ) ;
2005-04-17 02:20:36 +04:00
}
2011-07-24 08:10:41 +04:00
__set_current_state ( TASK_RUNNING ) ;
2010-04-20 17:03:51 +04:00
remove_wait_queue ( sk_sleep ( sk ) , & wait ) ;
2005-04-17 02:20:36 +04:00
if ( err )
goto done ;
newsock - > state = SS_CONNECTED ;
BT_DBG ( " new socket %p " , nsk ) ;
done :
release_sock ( sk ) ;
return err ;
}
static int rfcomm_sock_getname ( struct socket * sock , struct sockaddr * addr , int * len , int peer )
{
struct sockaddr_rc * sa = ( struct sockaddr_rc * ) addr ;
struct sock * sk = sock - > sk ;
BT_DBG ( " sock %p, sk %p " , sock , sk ) ;
2012-08-15 15:31:50 +04:00
memset ( sa , 0 , sizeof ( * sa ) ) ;
2005-04-17 02:20:36 +04:00
sa - > rc_family = AF_BLUETOOTH ;
sa - > rc_channel = rfcomm_pi ( sk ) - > channel ;
if ( peer )
bacpy ( & sa - > rc_bdaddr , & bt_sk ( sk ) - > dst ) ;
else
bacpy ( & sa - > rc_bdaddr , & bt_sk ( sk ) - > src ) ;
* len = sizeof ( struct sockaddr_rc ) ;
return 0 ;
}
static int rfcomm_sock_sendmsg ( struct kiocb * iocb , struct socket * sock ,
struct msghdr * msg , size_t len )
{
struct sock * sk = sock - > sk ;
struct rfcomm_dlc * d = rfcomm_pi ( sk ) - > dlc ;
struct sk_buff * skb ;
int sent = 0 ;
2009-01-15 23:56:48 +03:00
if ( test_bit ( RFCOMM_DEFER_SETUP , & d - > flags ) )
return - ENOTCONN ;
2005-04-17 02:20:36 +04:00
if ( msg - > msg_flags & MSG_OOB )
return - EOPNOTSUPP ;
if ( sk - > sk_shutdown & SEND_SHUTDOWN )
return - EPIPE ;
BT_DBG ( " sock %p, sk %p " , sock , sk ) ;
lock_sock ( sk ) ;
while ( len ) {
size_t size = min_t ( size_t , len , d - > mtu ) ;
2007-01-08 04:16:31 +03:00
int err ;
2007-02-09 17:24:33 +03:00
2005-04-17 02:20:36 +04:00
skb = sock_alloc_send_skb ( sk , size + RFCOMM_SKB_RESERVE ,
msg - > msg_flags & MSG_DONTWAIT , & err ) ;
2009-01-15 23:52:12 +03:00
if ( ! skb ) {
if ( sent = = 0 )
sent = err ;
2005-04-17 02:20:36 +04:00
break ;
2009-01-15 23:52:12 +03:00
}
2005-04-17 02:20:36 +04:00
skb_reserve ( skb , RFCOMM_SKB_HEAD_RESERVE ) ;
err = memcpy_fromiovec ( skb_put ( skb , size ) , msg - > msg_iov , size ) ;
if ( err ) {
kfree_skb ( skb ) ;
2007-01-08 04:16:31 +03:00
if ( sent = = 0 )
sent = err ;
2005-04-17 02:20:36 +04:00
break ;
}
2011-11-01 12:58:58 +04:00
skb - > priority = sk - > sk_priority ;
2005-04-17 02:20:36 +04:00
err = rfcomm_dlc_send ( d , skb ) ;
if ( err < 0 ) {
kfree_skb ( skb ) ;
2007-01-08 04:16:31 +03:00
if ( sent = = 0 )
sent = err ;
2005-04-17 02:20:36 +04:00
break ;
}
sent + = size ;
len - = size ;
}
release_sock ( sk ) ;
2007-01-08 04:16:31 +03:00
return sent ;
2005-04-17 02:20:36 +04:00
}
static int rfcomm_sock_recvmsg ( struct kiocb * iocb , struct socket * sock ,
struct msghdr * msg , size_t size , int flags )
{
struct sock * sk = sock - > sk ;
2009-01-15 23:56:48 +03:00
struct rfcomm_dlc * d = rfcomm_pi ( sk ) - > dlc ;
2010-09-08 21:05:28 +04:00
int len ;
2005-04-17 02:20:36 +04:00
2009-01-15 23:56:48 +03:00
if ( test_and_clear_bit ( RFCOMM_DEFER_SETUP , & d - > flags ) ) {
rfcomm_dlc_accept ( d ) ;
return 0 ;
}
2010-09-08 21:05:28 +04:00
len = bt_sock_stream_recvmsg ( iocb , sock , msg , size , flags ) ;
2005-04-17 02:20:36 +04:00
lock_sock ( sk ) ;
2010-09-08 21:05:28 +04:00
if ( ! ( flags & MSG_PEEK ) & & len > 0 )
atomic_sub ( len , & sk - > sk_rmem_alloc ) ;
2005-04-17 02:20:36 +04:00
if ( atomic_read ( & sk - > sk_rmem_alloc ) < = ( sk - > sk_rcvbuf > > 2 ) )
rfcomm_dlc_unthrottle ( rfcomm_pi ( sk ) - > dlc ) ;
release_sock ( sk ) ;
2010-09-08 21:05:28 +04:00
return len ;
2005-04-17 02:20:36 +04:00
}
2009-10-01 03:12:20 +04:00
static int rfcomm_sock_setsockopt_old ( struct socket * sock , int optname , char __user * optval , unsigned int optlen )
2005-04-17 02:20:36 +04:00
{
struct sock * sk = sock - > sk ;
int err = 0 ;
u32 opt ;
BT_DBG ( " sk %p " , sk ) ;
lock_sock ( sk ) ;
switch ( optname ) {
case RFCOMM_LM :
if ( get_user ( opt , ( u32 __user * ) optval ) ) {
err = - EFAULT ;
break ;
}
2009-01-15 23:58:40 +03:00
if ( opt & RFCOMM_LM_AUTH )
rfcomm_pi ( sk ) - > sec_level = BT_SECURITY_LOW ;
if ( opt & RFCOMM_LM_ENCRYPT )
rfcomm_pi ( sk ) - > sec_level = BT_SECURITY_MEDIUM ;
if ( opt & RFCOMM_LM_SECURE )
rfcomm_pi ( sk ) - > sec_level = BT_SECURITY_HIGH ;
rfcomm_pi ( sk ) - > role_switch = ( opt & RFCOMM_LM_MASTER ) ;
2005-04-17 02:20:36 +04:00
break ;
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
return err ;
}
2009-10-01 03:12:20 +04:00
static int rfcomm_sock_setsockopt ( struct socket * sock , int level , int optname , char __user * optval , unsigned int optlen )
2009-01-15 23:52:14 +03:00
{
struct sock * sk = sock - > sk ;
2009-01-15 23:58:40 +03:00
struct bt_security sec ;
2011-05-13 03:50:09 +04:00
int err = 0 ;
size_t len ;
2009-01-15 23:56:48 +03:00
u32 opt ;
2009-01-15 23:52:14 +03:00
BT_DBG ( " sk %p " , sk ) ;
if ( level = = SOL_RFCOMM )
return rfcomm_sock_setsockopt_old ( sock , optname , optval , optlen ) ;
2009-01-16 12:06:13 +03:00
if ( level ! = SOL_BLUETOOTH )
return - ENOPROTOOPT ;
2009-01-15 23:52:14 +03:00
lock_sock ( sk ) ;
switch ( optname ) {
2009-01-15 23:58:40 +03:00
case BT_SECURITY :
2009-01-16 12:06:13 +03:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
break ;
}
2009-01-15 23:58:40 +03:00
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_HIGH ) {
err = - EINVAL ;
break ;
}
rfcomm_pi ( sk ) - > sec_level = sec . level ;
break ;
2009-01-15 23:56:48 +03:00
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 ;
}
2012-05-16 19:17:10 +04:00
if ( opt )
set_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ;
else
clear_bit ( BT_SK_DEFER_SETUP , & bt_sk ( sk ) - > flags ) ;
2009-01-15 23:56:48 +03:00
break ;
2009-01-15 23:52:14 +03:00
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
return err ;
}
static int rfcomm_sock_getsockopt_old ( struct socket * sock , int optname , char __user * optval , int __user * optlen )
2005-04-17 02:20:36 +04:00
{
struct sock * sk = sock - > sk ;
struct rfcomm_conninfo cinfo ;
2011-04-14 03:23:55 +04:00
struct l2cap_conn * conn = l2cap_pi ( sk ) - > chan - > conn ;
2005-04-17 02:20:36 +04:00
int len , err = 0 ;
2009-01-15 23:58:40 +03:00
u32 opt ;
2005-04-17 02:20:36 +04:00
BT_DBG ( " sk %p " , sk ) ;
if ( get_user ( len , optlen ) )
return - EFAULT ;
lock_sock ( sk ) ;
switch ( optname ) {
case RFCOMM_LM :
2009-01-15 23:58:40 +03:00
switch ( rfcomm_pi ( sk ) - > sec_level ) {
case BT_SECURITY_LOW :
opt = RFCOMM_LM_AUTH ;
break ;
case BT_SECURITY_MEDIUM :
opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT ;
break ;
case BT_SECURITY_HIGH :
opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT |
RFCOMM_LM_SECURE ;
break ;
default :
opt = 0 ;
break ;
}
if ( rfcomm_pi ( sk ) - > role_switch )
opt | = RFCOMM_LM_MASTER ;
if ( put_user ( opt , ( u32 __user * ) optval ) )
2005-04-17 02:20:36 +04:00
err = - EFAULT ;
break ;
case RFCOMM_CONNINFO :
2009-01-15 23:56:48 +03:00
if ( sk - > sk_state ! = BT_CONNECTED & &
! rfcomm_pi ( sk ) - > dlc - > defer_setup ) {
2005-04-17 02:20:36 +04: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 = conn - > hcon - > handle ;
memcpy ( cinfo . dev_class , conn - > hcon - > dev_class , 3 ) ;
2005-04-17 02:20:36 +04: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 ) ;
2009-01-15 23:52:14 +03:00
return err ;
}
static int rfcomm_sock_getsockopt ( struct socket * sock , int level , int optname , char __user * optval , int __user * optlen )
{
struct sock * sk = sock - > sk ;
2009-01-15 23:58:40 +03:00
struct bt_security sec ;
2009-01-15 23:52:14 +03:00
int len , err = 0 ;
BT_DBG ( " sk %p " , sk ) ;
if ( level = = SOL_RFCOMM )
return rfcomm_sock_getsockopt_old ( sock , optname , optval , optlen ) ;
2009-01-16 12:06:13 +03:00
if ( level ! = SOL_BLUETOOTH )
return - ENOPROTOOPT ;
2009-01-15 23:52:14 +03:00
if ( get_user ( len , optlen ) )
return - EFAULT ;
lock_sock ( sk ) ;
switch ( optname ) {
2009-01-15 23:58:40 +03:00
case BT_SECURITY :
2009-01-16 12:06:13 +03:00
if ( sk - > sk_type ! = SOCK_STREAM ) {
err = - EINVAL ;
break ;
}
2009-01-15 23:58:40 +03:00
sec . level = rfcomm_pi ( sk ) - > sec_level ;
2012-08-15 15:31:48 +04:00
sec . key_size = 0 ;
2009-01-15 23:58:40 +03:00
len = min_t ( unsigned int , len , sizeof ( sec ) ) ;
if ( copy_to_user ( optval , ( char * ) & sec , len ) )
err = - EFAULT ;
break ;
2009-01-15 23:56:48 +03:00
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 ) )
2009-01-15 23:56:48 +03:00
err = - EFAULT ;
break ;
2009-01-15 23:52:14 +03:00
default :
err = - ENOPROTOOPT ;
break ;
}
release_sock ( sk ) ;
2005-04-17 02:20:36 +04:00
return err ;
}
static int rfcomm_sock_ioctl ( struct socket * sock , unsigned int cmd , unsigned long arg )
{
2008-12-09 12:04:27 +03:00
struct sock * sk __maybe_unused = sock - > sk ;
2005-04-17 02:20:36 +04:00
int err ;
2008-12-09 12:04:27 +03:00
BT_DBG ( " sk %p cmd %x arg %lx " , sk , cmd , arg ) ;
2005-04-17 02:20:36 +04:00
2008-07-14 22:13:50 +04:00
err = bt_sock_ioctl ( sock , cmd , arg ) ;
2005-04-17 02:20:36 +04:00
2008-07-14 22:13:50 +04:00
if ( err = = - ENOIOCTLCMD ) {
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_BT_RFCOMM_TTY
2008-07-14 22:13:50 +04:00
lock_sock ( sk ) ;
err = rfcomm_dev_ioctl ( sk , cmd , ( void __user * ) arg ) ;
release_sock ( sk ) ;
2005-04-17 02:20:36 +04:00
# else
2008-07-14 22:13:50 +04:00
err = - EOPNOTSUPP ;
2005-04-17 02:20:36 +04:00
# endif
2008-07-14 22:13:50 +04:00
}
2005-04-17 02:20:36 +04:00
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 ) ;
2010-12-01 17:58:23 +03:00
if ( ! sk )
return 0 ;
2005-04-17 02:20:36 +04:00
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 ;
err = rfcomm_sock_shutdown ( sock , 2 ) ;
sock_orphan ( sk ) ;
rfcomm_sock_kill ( sk ) ;
return err ;
}
2007-02-09 17:24:33 +03:00
/* ---- RFCOMM core layer callbacks ----
2005-04-17 02:20:36 +04:00
*
* called under rfcomm_lock ( )
*/
int rfcomm_connect_ind ( struct rfcomm_session * s , u8 channel , struct rfcomm_dlc * * d )
{
struct sock * sk , * parent ;
bdaddr_t src , dst ;
int result = 0 ;
BT_DBG ( " session %p channel %d " , s , channel ) ;
rfcomm_session_getaddr ( s , & src , & dst ) ;
/* Check if we have socket listening on channel */
parent = rfcomm_get_sock_by_channel ( BT_LISTEN , channel , & src ) ;
if ( ! parent )
return 0 ;
2010-11-01 21:43:53 +03:00
bh_lock_sock ( parent ) ;
2005-04-17 02:20:36 +04:00
/* Check for backlog size */
if ( sk_acceptq_is_full ( parent ) ) {
2007-02-09 17:24:33 +03:00
BT_DBG ( " backlog full %d " , parent - > sk_ack_backlog ) ;
2005-04-17 02:20:36 +04:00
goto done ;
}
2008-03-25 20:26:21 +03:00
sk = rfcomm_sock_alloc ( sock_net ( parent ) , NULL , BTPROTO_RFCOMM , GFP_ATOMIC ) ;
2005-04-17 02:20:36 +04:00
if ( ! sk )
goto done ;
2012-01-22 02:28:34 +04:00
bt_sock_reclassify_lock ( sk , BTPROTO_RFCOMM ) ;
2005-04-17 02:20:36 +04:00
rfcomm_sock_init ( sk , parent ) ;
bacpy ( & bt_sk ( sk ) - > src , & src ) ;
bacpy ( & bt_sk ( sk ) - > dst , & dst ) ;
rfcomm_pi ( sk ) - > channel = channel ;
sk - > sk_state = BT_CONFIG ;
bt_accept_enqueue ( parent , sk ) ;
/* Accept connection and return socket DLC */
* d = rfcomm_pi ( sk ) - > dlc ;
result = 1 ;
done :
bh_unlock_sock ( parent ) ;
2009-01-15 23:56:48 +03:00
2012-05-16 19:17:10 +04:00
if ( test_bit ( BT_SK_DEFER_SETUP , & bt_sk ( parent ) - > flags ) )
2009-01-15 23:56:48 +03:00
parent - > sk_state_change ( parent ) ;
2005-04-17 02:20:36 +04:00
return result ;
}
2010-03-21 07:27:45 +03:00
static int rfcomm_sock_debugfs_show ( struct seq_file * f , void * p )
2005-04-17 02:20:36 +04:00
{
struct sock * sk ;
struct hlist_node * node ;
2011-12-27 21:28:44 +04:00
read_lock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
2005-11-08 20:57:38 +03:00
sk_for_each ( sk , node , & rfcomm_sk_list . head ) {
2012-09-25 13:49:44 +04:00
seq_printf ( f , " %pMR %pMR %d %d \n " ,
& bt_sk ( sk ) - > src , & bt_sk ( sk ) - > dst ,
sk - > sk_state , rfcomm_pi ( sk ) - > channel ) ;
2005-11-08 20:57:38 +03:00
}
2005-04-17 02:20:36 +04:00
2011-12-27 21:28:44 +04:00
read_unlock ( & rfcomm_sk_list . lock ) ;
2005-04-17 02:20:36 +04:00
2010-03-21 07:27:45 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2010-03-21 07:27:45 +03:00
static int rfcomm_sock_debugfs_open ( struct inode * inode , struct file * file )
{
return single_open ( file , rfcomm_sock_debugfs_show , inode - > i_private ) ;
}
static const struct file_operations rfcomm_sock_debugfs_fops = {
. open = rfcomm_sock_debugfs_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
static struct dentry * rfcomm_sock_debugfs ;
2005-04-17 02:20:36 +04:00
2005-12-22 23:49:22 +03:00
static const struct proto_ops rfcomm_sock_ops = {
2005-04-17 02:20:36 +04:00
. family = PF_BLUETOOTH ,
. owner = THIS_MODULE ,
. release = rfcomm_sock_release ,
. bind = rfcomm_sock_bind ,
. connect = rfcomm_sock_connect ,
. listen = rfcomm_sock_listen ,
. accept = rfcomm_sock_accept ,
. getname = rfcomm_sock_getname ,
. sendmsg = rfcomm_sock_sendmsg ,
. recvmsg = rfcomm_sock_recvmsg ,
. shutdown = rfcomm_sock_shutdown ,
. setsockopt = rfcomm_sock_setsockopt ,
. getsockopt = rfcomm_sock_getsockopt ,
. ioctl = rfcomm_sock_ioctl ,
. poll = bt_sock_poll ,
. socketpair = sock_no_socketpair ,
. mmap = sock_no_mmap
} ;
2009-10-05 09:58:39 +04:00
static const struct net_proto_family rfcomm_sock_family_ops = {
2005-04-17 02:20:36 +04:00
. family = PF_BLUETOOTH ,
. owner = THIS_MODULE ,
. create = rfcomm_sock_create
} ;
2005-11-08 20:57:38 +03:00
int __init rfcomm_init_sockets ( void )
2005-04-17 02:20:36 +04:00
{
int err ;
err = proto_register ( & rfcomm_proto , 0 ) ;
if ( err < 0 )
return err ;
err = bt_sock_register ( BTPROTO_RFCOMM , & rfcomm_sock_family_ops ) ;
2012-07-25 20:29:49 +04:00
if ( err < 0 ) {
BT_ERR ( " RFCOMM socket layer registration failed " ) ;
goto error ;
}
err = bt_procfs_init ( THIS_MODULE , & init_net , " rfcomm " , & rfcomm_sk_list , NULL ) ;
if ( err < 0 ) {
BT_ERR ( " Failed to create RFCOMM proc file " ) ;
bt_sock_unregister ( BTPROTO_RFCOMM ) ;
2005-04-17 02:20:36 +04:00
goto error ;
2012-07-25 20:29:49 +04:00
}
2005-04-17 02:20:36 +04:00
2010-03-21 07:27:45 +03:00
if ( bt_debugfs ) {
rfcomm_sock_debugfs = debugfs_create_file ( " rfcomm " , 0444 ,
bt_debugfs , NULL , & rfcomm_sock_debugfs_fops ) ;
if ( ! rfcomm_sock_debugfs )
BT_ERR ( " Failed to create RFCOMM debug file " ) ;
}
2005-04-17 02:20:36 +04:00
BT_INFO ( " RFCOMM socket layer initialized " ) ;
return 0 ;
error :
proto_unregister ( & rfcomm_proto ) ;
return err ;
}
2010-07-24 09:04:45 +04:00
void __exit rfcomm_cleanup_sockets ( void )
2005-04-17 02:20:36 +04:00
{
2012-07-25 20:29:49 +04:00
bt_procfs_cleanup ( & init_net , " rfcomm " ) ;
2010-03-21 07:27:45 +03:00
debugfs_remove ( rfcomm_sock_debugfs ) ;
2005-04-17 02:20:36 +04:00
if ( bt_sock_unregister ( BTPROTO_RFCOMM ) < 0 )
BT_ERR ( " RFCOMM socket layer unregistration failed " ) ;
proto_unregister ( & rfcomm_proto ) ;
}