aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index b79fb7561836..bec3e043b254 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -390,6 +390,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
390 struct sock *sk = sock->sk; 390 struct sock *sk = sock->sk;
391 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 391 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
392 struct bt_security sec; 392 struct bt_security sec;
393 struct bt_power pwr;
393 int len, err = 0; 394 int len, err = 0;
394 395
395 BT_DBG("sk %p", sk); 396 BT_DBG("sk %p", sk);
@@ -438,6 +439,21 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
438 439
439 break; 440 break;
440 441
442 case BT_POWER:
443 if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM
444 && sk->sk_type != SOCK_RAW) {
445 err = -EINVAL;
446 break;
447 }
448
449 pwr.force_active = chan->force_active;
450
451 len = min_t(unsigned int, len, sizeof(pwr));
452 if (copy_to_user(optval, (char *) &pwr, len))
453 err = -EFAULT;
454
455 break;
456
441 default: 457 default:
442 err = -ENOPROTOOPT; 458 err = -ENOPROTOOPT;
443 break; 459 break;
@@ -538,6 +554,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
538 struct sock *sk = sock->sk; 554 struct sock *sk = sock->sk;
539 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 555 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
540 struct bt_security sec; 556 struct bt_security sec;
557 struct bt_power pwr;
541 int len, err = 0; 558 int len, err = 0;
542 u32 opt; 559 u32 opt;
543 560
@@ -614,6 +631,23 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
614 chan->flushable = opt; 631 chan->flushable = opt;
615 break; 632 break;
616 633
634 case BT_POWER:
635 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED &&
636 chan->chan_type != L2CAP_CHAN_RAW) {
637 err = -EINVAL;
638 break;
639 }
640
641 pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
642
643 len = min_t(unsigned int, sizeof(pwr), optlen);
644 if (copy_from_user((char *) &pwr, optval, len)) {
645 err = -EFAULT;
646 break;
647 }
648 chan->force_active = pwr.force_active;
649 break;
650
617 default: 651 default:
618 err = -ENOPROTOOPT; 652 err = -ENOPROTOOPT;
619 break; 653 break;
@@ -771,6 +805,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
771 chan->role_switch = pchan->role_switch; 805 chan->role_switch = pchan->role_switch;
772 chan->force_reliable = pchan->force_reliable; 806 chan->force_reliable = pchan->force_reliable;
773 chan->flushable = pchan->flushable; 807 chan->flushable = pchan->flushable;
808 chan->force_active = pchan->force_active;
774 } else { 809 } else {
775 810
776 switch (sk->sk_type) { 811 switch (sk->sk_type) {
@@ -801,6 +836,7 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent)
801 chan->role_switch = 0; 836 chan->role_switch = 0;
802 chan->force_reliable = 0; 837 chan->force_reliable = 0;
803 chan->flushable = BT_FLUSHABLE_OFF; 838 chan->flushable = BT_FLUSHABLE_OFF;
839 chan->force_active = BT_POWER_FORCE_ACTIVE_ON;
804 } 840 }
805 841
806 /* Default config options */ 842 /* Default config options */