aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r--net/bluetooth/sco.c91
1 files changed, 55 insertions, 36 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index cb4fb7837e5..c0b9ad0524e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -41,6 +41,7 @@
41#include <linux/debugfs.h> 41#include <linux/debugfs.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/list.h> 43#include <linux/list.h>
44#include <linux/security.h>
44#include <net/sock.h> 45#include <net/sock.h>
45 46
46#include <asm/system.h> 47#include <asm/system.h>
@@ -177,6 +178,7 @@ static int sco_connect(struct sock *sk)
177{ 178{
178 bdaddr_t *src = &bt_sk(sk)->src; 179 bdaddr_t *src = &bt_sk(sk)->src;
179 bdaddr_t *dst = &bt_sk(sk)->dst; 180 bdaddr_t *dst = &bt_sk(sk)->dst;
181 __u16 pkt_type = sco_pi(sk)->pkt_type;
180 struct sco_conn *conn; 182 struct sco_conn *conn;
181 struct hci_conn *hcon; 183 struct hci_conn *hcon;
182 struct hci_dev *hdev; 184 struct hci_dev *hdev;
@@ -192,10 +194,12 @@ static int sco_connect(struct sock *sk)
192 194
193 if (lmp_esco_capable(hdev) && !disable_esco) 195 if (lmp_esco_capable(hdev) && !disable_esco)
194 type = ESCO_LINK; 196 type = ESCO_LINK;
195 else 197 else {
196 type = SCO_LINK; 198 type = SCO_LINK;
199 pkt_type &= SCO_ESCO_MASK;
200 }
197 201
198 hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING); 202 hcon = hci_connect(hdev, type, pkt_type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
199 if (IS_ERR(hcon)) { 203 if (IS_ERR(hcon)) {
200 err = PTR_ERR(hcon); 204 err = PTR_ERR(hcon);
201 goto done; 205 goto done;
@@ -403,8 +407,10 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
403{ 407{
404 BT_DBG("sk %p", sk); 408 BT_DBG("sk %p", sk);
405 409
406 if (parent) 410 if (parent) {
407 sk->sk_type = parent->sk_type; 411 sk->sk_type = parent->sk_type;
412 security_sk_clone(parent, sk);
413 }
408} 414}
409 415
410static struct proto sco_proto = { 416static struct proto sco_proto = {
@@ -460,18 +466,22 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
460 return 0; 466 return 0;
461} 467}
462 468
463static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 469static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
464{ 470{
465 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; 471 struct sockaddr_sco sa;
466 struct sock *sk = sock->sk; 472 struct sock *sk = sock->sk;
467 bdaddr_t *src = &sa->sco_bdaddr; 473 bdaddr_t *src = &sa.sco_bdaddr;
468 int err = 0; 474 int len, err = 0;
469 475
470 BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr)); 476 BT_DBG("sk %p %s", sk, batostr(&sa.sco_bdaddr));
471 477
472 if (!addr || addr->sa_family != AF_BLUETOOTH) 478 if (!addr || addr->sa_family != AF_BLUETOOTH)
473 return -EINVAL; 479 return -EINVAL;
474 480
481 memset(&sa, 0, sizeof(sa));
482 len = min_t(unsigned int, sizeof(sa), alen);
483 memcpy(&sa, addr, len);
484
475 lock_sock(sk); 485 lock_sock(sk);
476 486
477 if (sk->sk_state != BT_OPEN) { 487 if (sk->sk_state != BT_OPEN) {
@@ -485,7 +495,8 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
485 err = -EADDRINUSE; 495 err = -EADDRINUSE;
486 } else { 496 } else {
487 /* Save source address */ 497 /* Save source address */
488 bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr); 498 bacpy(&bt_sk(sk)->src, &sa.sco_bdaddr);
499 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
489 sk->sk_state = BT_BOUND; 500 sk->sk_state = BT_BOUND;
490 } 501 }
491 502
@@ -498,27 +509,34 @@ done:
498 509
499static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) 510static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
500{ 511{
501 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
502 struct sock *sk = sock->sk; 512 struct sock *sk = sock->sk;
503 int err = 0; 513 struct sockaddr_sco sa;
504 514 int len, err = 0;
505 515
506 BT_DBG("sk %p", sk); 516 BT_DBG("sk %p", sk);
507 517
508 if (alen < sizeof(struct sockaddr_sco) || 518 if (!addr || addr->sa_family != AF_BLUETOOTH)
509 addr->sa_family != AF_BLUETOOTH)
510 return -EINVAL; 519 return -EINVAL;
511 520
512 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) 521 memset(&sa, 0, sizeof(sa));
513 return -EBADFD; 522 len = min_t(unsigned int, sizeof(sa), alen);
514 523 memcpy(&sa, addr, len);
515 if (sk->sk_type != SOCK_SEQPACKET)
516 return -EINVAL;
517 524
518 lock_sock(sk); 525 lock_sock(sk);
519 526
527 if (sk->sk_type != SOCK_SEQPACKET) {
528 err = -EINVAL;
529 goto done;
530 }
531
532 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
533 err = -EBADFD;
534 goto done;
535 }
536
520 /* Set destination address and psm */ 537 /* Set destination address and psm */
521 bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr); 538 bacpy(&bt_sk(sk)->dst, &sa.sco_bdaddr);
539 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
522 540
523 err = sco_connect(sk); 541 err = sco_connect(sk);
524 if (err) 542 if (err)
@@ -564,30 +582,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
564 582
565 lock_sock(sk); 583 lock_sock(sk);
566 584
567 if (sk->sk_state != BT_LISTEN) {
568 err = -EBADFD;
569 goto done;
570 }
571
572 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); 585 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
573 586
574 BT_DBG("sk %p timeo %ld", sk, timeo); 587 BT_DBG("sk %p timeo %ld", sk, timeo);
575 588
576 /* Wait for an incoming connection. (wake-one). */ 589 /* Wait for an incoming connection. (wake-one). */
577 add_wait_queue_exclusive(sk_sleep(sk), &wait); 590 add_wait_queue_exclusive(sk_sleep(sk), &wait);
578 while (!(ch = bt_accept_dequeue(sk, newsock))) { 591 while (1) {
579 set_current_state(TASK_INTERRUPTIBLE); 592 set_current_state(TASK_INTERRUPTIBLE);
580 if (!timeo) { 593
581 err = -EAGAIN; 594 if (sk->sk_state != BT_LISTEN) {
595 err = -EBADFD;
582 break; 596 break;
583 } 597 }
584 598
585 release_sock(sk); 599 ch = bt_accept_dequeue(sk, newsock);
586 timeo = schedule_timeout(timeo); 600 if (ch)
587 lock_sock(sk); 601 break;
588 602
589 if (sk->sk_state != BT_LISTEN) { 603 if (!timeo) {
590 err = -EBADFD; 604 err = -EAGAIN;
591 break; 605 break;
592 } 606 }
593 607
@@ -595,8 +609,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
595 err = sock_intr_errno(timeo); 609 err = sock_intr_errno(timeo);
596 break; 610 break;
597 } 611 }
612
613 release_sock(sk);
614 timeo = schedule_timeout(timeo);
615 lock_sock(sk);
598 } 616 }
599 set_current_state(TASK_RUNNING); 617 __set_current_state(TASK_RUNNING);
600 remove_wait_queue(sk_sleep(sk), &wait); 618 remove_wait_queue(sk_sleep(sk), &wait);
601 619
602 if (err) 620 if (err)
@@ -625,6 +643,7 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len
625 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst); 643 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
626 else 644 else
627 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src); 645 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
646 sa->sco_pkt_type = sco_pi(sk)->pkt_type;
628 647
629 return 0; 648 return 0;
630} 649}
@@ -932,7 +951,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
932 if (conn) 951 if (conn)
933 sco_conn_ready(conn); 952 sco_conn_ready(conn);
934 } else 953 } else
935 sco_conn_del(hcon, bt_err(status)); 954 sco_conn_del(hcon, bt_to_errno(status));
936 955
937 return 0; 956 return 0;
938} 957}
@@ -944,7 +963,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
944 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) 963 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
945 return -EINVAL; 964 return -EINVAL;
946 965
947 sco_conn_del(hcon, bt_err(reason)); 966 sco_conn_del(hcon, bt_to_errno(reason));
948 967
949 return 0; 968 return 0;
950} 969}