aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-10-20 08:55:10 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-22 05:59:47 -0400
commitb6a0dc822497e1c0b9e8c4add270cc27fce48454 (patch)
treeecfd0a08f62e4c6c7d1e63e62c04b6c17ca09cb6 /net/bluetooth/hci_event.c
parentdae6a0f6636d05bcb28ece1f3630b23ed2d66e18 (diff)
[Bluetooth] Add support for handling simple eSCO links
With the Bluetooth 1.2 specification the Extended SCO feature for better audio connections was introduced. So far the Bluetooth core wasn't able to handle any eSCO connections correctly. This patch adds simple eSCO support while keeping backward compatibility with older devices. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c99
1 files changed, 86 insertions, 13 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e2cfeea5ee72..46df2e403df8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -511,11 +511,11 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
511 struct hci_conn *acl, *sco; 511 struct hci_conn *acl, *sco;
512 __u16 handle; 512 __u16 handle;
513 513
514 BT_DBG("%s status 0x%x", hdev->name, status);
515
514 if (!status) 516 if (!status)
515 return; 517 return;
516 518
517 BT_DBG("%s status 0x%x", hdev->name, status);
518
519 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO); 519 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
520 if (!cp) 520 if (!cp)
521 return; 521 return;
@@ -544,7 +544,34 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
544 544
545static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) 545static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
546{ 546{
547 struct hci_cp_setup_sync_conn *cp;
548 struct hci_conn *acl, *sco;
549 __u16 handle;
550
547 BT_DBG("%s status 0x%x", hdev->name, status); 551 BT_DBG("%s status 0x%x", hdev->name, status);
552
553 if (!status)
554 return;
555
556 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
557 if (!cp)
558 return;
559
560 handle = __le16_to_cpu(cp->handle);
561
562 BT_DBG("%s handle %d", hdev->name, handle);
563
564 hci_dev_lock(hdev);
565
566 acl = hci_conn_hash_lookup_handle(hdev, handle);
567 if (acl && (sco = acl->link)) {
568 sco->state = BT_CLOSED;
569
570 hci_proto_connect_cfm(sco, status);
571 hci_conn_del(sco);
572 }
573
574 hci_dev_unlock(hdev);
548} 575}
549 576
550static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) 577static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
@@ -692,9 +719,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
692 if (conn->type == ACL_LINK) { 719 if (conn->type == ACL_LINK) {
693 struct hci_conn *sco = conn->link; 720 struct hci_conn *sco = conn->link;
694 if (sco) { 721 if (sco) {
695 if (!ev->status) 722 if (!ev->status) {
696 hci_add_sco(sco, conn->handle); 723 if (lmp_esco_capable(hdev))
697 else { 724 hci_setup_sync(sco, conn->handle);
725 else
726 hci_add_sco(sco, conn->handle);
727 } else {
698 hci_proto_connect_cfm(sco, ev->status); 728 hci_proto_connect_cfm(sco, ev->status);
699 hci_conn_del(sco); 729 hci_conn_del(sco);
700 } 730 }
@@ -724,9 +754,9 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
724 if (mask & HCI_LM_ACCEPT) { 754 if (mask & HCI_LM_ACCEPT) {
725 /* Connection accepted */ 755 /* Connection accepted */
726 struct hci_conn *conn; 756 struct hci_conn *conn;
727 struct hci_cp_accept_conn_req cp;
728 757
729 hci_dev_lock(hdev); 758 hci_dev_lock(hdev);
759
730 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 760 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
731 if (!conn) { 761 if (!conn) {
732 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { 762 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
@@ -735,18 +765,39 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
735 return; 765 return;
736 } 766 }
737 } 767 }
768
738 memcpy(conn->dev_class, ev->dev_class, 3); 769 memcpy(conn->dev_class, ev->dev_class, 3);
739 conn->state = BT_CONNECT; 770 conn->state = BT_CONNECT;
771
740 hci_dev_unlock(hdev); 772 hci_dev_unlock(hdev);
741 773
742 bacpy(&cp.bdaddr, &ev->bdaddr); 774 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
775 struct hci_cp_accept_conn_req cp;
743 776
744 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) 777 bacpy(&cp.bdaddr, &ev->bdaddr);
745 cp.role = 0x00; /* Become master */ 778
746 else 779 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
747 cp.role = 0x01; /* Remain slave */ 780 cp.role = 0x00; /* Become master */
781 else
782 cp.role = 0x01; /* Remain slave */
783
784 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
785 sizeof(cp), &cp);
786 } else {
787 struct hci_cp_accept_sync_conn_req cp;
788
789 bacpy(&cp.bdaddr, &ev->bdaddr);
790 cp.pkt_type = cpu_to_le16(hdev->esco_type);
791
792 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
793 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
794 cp.max_latency = cpu_to_le16(0xffff);
795 cp.content_format = cpu_to_le16(hdev->voice_setting);
796 cp.retrans_effort = 0xff;
748 797
749 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); 798 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
799 sizeof(cp), &cp);
800 }
750 } else { 801 } else {
751 /* Connection rejected */ 802 /* Connection rejected */
752 struct hci_cp_reject_conn_req cp; 803 struct hci_cp_reject_conn_req cp;
@@ -1254,7 +1305,29 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1254 1305
1255static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1306static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1256{ 1307{
1257 BT_DBG("%s", hdev->name); 1308 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1309 struct hci_conn *conn;
1310
1311 BT_DBG("%s status %d", hdev->name, ev->status);
1312
1313 hci_dev_lock(hdev);
1314
1315 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1316 if (!conn)
1317 goto unlock;
1318
1319 if (!ev->status) {
1320 conn->handle = __le16_to_cpu(ev->handle);
1321 conn->state = BT_CONNECTED;
1322 } else
1323 conn->state = BT_CLOSED;
1324
1325 hci_proto_connect_cfm(conn, ev->status);
1326 if (ev->status)
1327 hci_conn_del(conn);
1328
1329unlock:
1330 hci_dev_unlock(hdev);
1258} 1331}
1259 1332
1260static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) 1333static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)