@@ -395,6 +395,24 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
395
395
return sizeof (struct sockaddr_l2 );
396
396
}
397
397
398
+ static int l2cap_get_mode (struct l2cap_chan * chan )
399
+ {
400
+ switch (chan -> mode ) {
401
+ case L2CAP_MODE_BASIC :
402
+ return BT_MODE_BASIC ;
403
+ case L2CAP_MODE_ERTM :
404
+ return BT_MODE_ERTM ;
405
+ case L2CAP_MODE_STREAMING :
406
+ return BT_MODE_STREAMING ;
407
+ case L2CAP_MODE_LE_FLOWCTL :
408
+ return BT_MODE_LE_FLOWCTL ;
409
+ case L2CAP_MODE_EXT_FLOWCTL :
410
+ return BT_MODE_EXT_FLOWCTL ;
411
+ }
412
+
413
+ return - EINVAL ;
414
+ }
415
+
398
416
static int l2cap_sock_getsockopt_old (struct socket * sock , int optname ,
399
417
char __user * optval , int __user * optlen )
400
418
{
@@ -522,7 +540,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
522
540
struct bt_security sec ;
523
541
struct bt_power pwr ;
524
542
u32 phys ;
525
- int len , err = 0 ;
543
+ int len , mode , err = 0 ;
526
544
527
545
BT_DBG ("sk %p" , sk );
528
546
@@ -638,6 +656,27 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname,
638
656
err = - EFAULT ;
639
657
break ;
640
658
659
+ case BT_MODE :
660
+ if (!enable_ecred ) {
661
+ err = - ENOPROTOOPT ;
662
+ break ;
663
+ }
664
+
665
+ if (chan -> chan_type != L2CAP_CHAN_CONN_ORIENTED ) {
666
+ err = - EINVAL ;
667
+ break ;
668
+ }
669
+
670
+ mode = l2cap_get_mode (chan );
671
+ if (mode < 0 ) {
672
+ err = mode ;
673
+ break ;
674
+ }
675
+
676
+ if (put_user (mode , (u8 __user * ) optval ))
677
+ err = - EFAULT ;
678
+ break ;
679
+
641
680
default :
642
681
err = - ENOPROTOOPT ;
643
682
break ;
@@ -780,6 +819,45 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
780
819
return err ;
781
820
}
782
821
822
+ static int l2cap_set_mode (struct l2cap_chan * chan , u8 mode )
823
+ {
824
+ switch (mode ) {
825
+ case BT_MODE_BASIC :
826
+ if (bdaddr_type_is_le (chan -> src_type ))
827
+ return - EINVAL ;
828
+ mode = L2CAP_MODE_BASIC ;
829
+ clear_bit (CONF_STATE2_DEVICE , & chan -> conf_state );
830
+ break ;
831
+ case BT_MODE_ERTM :
832
+ if (!disable_ertm || bdaddr_type_is_le (chan -> src_type ))
833
+ return - EINVAL ;
834
+ mode = L2CAP_MODE_ERTM ;
835
+ break ;
836
+ case BT_MODE_STREAMING :
837
+ if (!disable_ertm || bdaddr_type_is_le (chan -> src_type ))
838
+ return - EINVAL ;
839
+ mode = L2CAP_MODE_STREAMING ;
840
+ break ;
841
+ case BT_MODE_LE_FLOWCTL :
842
+ if (!bdaddr_type_is_le (chan -> src_type ))
843
+ return - EINVAL ;
844
+ mode = L2CAP_MODE_LE_FLOWCTL ;
845
+ break ;
846
+ case BT_MODE_EXT_FLOWCTL :
847
+ /* TODO: Add support for ECRED PDUs to BR/EDR */
848
+ if (!bdaddr_type_is_le (chan -> src_type ))
849
+ return - EINVAL ;
850
+ mode = L2CAP_MODE_EXT_FLOWCTL ;
851
+ break ;
852
+ default :
853
+ return - EINVAL ;
854
+ }
855
+
856
+ chan -> mode = mode ;
857
+
858
+ return 0 ;
859
+ }
860
+
783
861
static int l2cap_sock_setsockopt (struct socket * sock , int level , int optname ,
784
862
char __user * optval , unsigned int optlen )
785
863
{
@@ -985,6 +1063,39 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
985
1063
986
1064
break ;
987
1065
1066
+ case BT_MODE :
1067
+ if (!enable_ecred ) {
1068
+ err = - ENOPROTOOPT ;
1069
+ break ;
1070
+ }
1071
+
1072
+ BT_DBG ("sk->sk_state %u" , sk -> sk_state );
1073
+
1074
+ if (sk -> sk_state != BT_BOUND ) {
1075
+ err = - EINVAL ;
1076
+ break ;
1077
+ }
1078
+
1079
+ if (chan -> chan_type != L2CAP_CHAN_CONN_ORIENTED ) {
1080
+ err = - EINVAL ;
1081
+ break ;
1082
+ }
1083
+
1084
+ if (get_user (opt , (u8 __user * ) optval )) {
1085
+ err = - EFAULT ;
1086
+ break ;
1087
+ }
1088
+
1089
+ BT_DBG ("opt %u" , opt );
1090
+
1091
+ err = l2cap_set_mode (chan , opt );
1092
+ if (err )
1093
+ break ;
1094
+
1095
+ BT_DBG ("mode 0x%2.2x" , chan -> mode );
1096
+
1097
+ break ;
1098
+
988
1099
default :
989
1100
err = - ENOPROTOOPT ;
990
1101
break ;
0 commit comments