aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c39
-rw-r--r--net/bluetooth/hci_core.c22
-rw-r--r--net/bluetooth/hci_event.c99
-rw-r--r--net/bluetooth/sco.c12
4 files changed, 150 insertions, 22 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 797a30bec6fd..9483320f6dad 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -78,9 +78,9 @@ void hci_acl_connect(struct hci_conn *conn)
78 78
79 cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK); 79 cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
80 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) 80 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
81 cp.role_switch = 0x01; 81 cp.role_switch = 0x01;
82 else 82 else
83 cp.role_switch = 0x00; 83 cp.role_switch = 0x00;
84 84
85 hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp); 85 hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
86} 86}
@@ -127,6 +127,28 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
127 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); 127 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
128} 128}
129 129
130void hci_setup_sync(struct hci_conn *conn, __u16 handle)
131{
132 struct hci_dev *hdev = conn->hdev;
133 struct hci_cp_setup_sync_conn cp;
134
135 BT_DBG("%p", conn);
136
137 conn->state = BT_CONNECT;
138 conn->out = 1;
139
140 cp.handle = cpu_to_le16(handle);
141 cp.pkt_type = cpu_to_le16(hdev->esco_type);
142
143 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
144 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
145 cp.max_latency = cpu_to_le16(0xffff);
146 cp.voice_setting = cpu_to_le16(hdev->voice_setting);
147 cp.retrans_effort = 0xff;
148
149 hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
150}
151
130static void hci_conn_timeout(unsigned long arg) 152static void hci_conn_timeout(unsigned long arg)
131{ 153{
132 struct hci_conn *conn = (void *) arg; 154 struct hci_conn *conn = (void *) arg;
@@ -141,7 +163,10 @@ static void hci_conn_timeout(unsigned long arg)
141 163
142 switch (conn->state) { 164 switch (conn->state) {
143 case BT_CONNECT: 165 case BT_CONNECT:
144 hci_acl_connect_cancel(conn); 166 if (conn->type == ACL_LINK)
167 hci_acl_connect_cancel(conn);
168 else
169 hci_acl_disconn(conn, 0x13);
145 break; 170 break;
146 case BT_CONNECTED: 171 case BT_CONNECTED:
147 hci_acl_disconn(conn, 0x13); 172 hci_acl_disconn(conn, 0x13);
@@ -328,8 +353,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
328 hci_conn_hold(sco); 353 hci_conn_hold(sco);
329 354
330 if (acl->state == BT_CONNECTED && 355 if (acl->state == BT_CONNECTED &&
331 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) 356 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
332 hci_add_sco(sco, acl->handle); 357 if (lmp_esco_capable(hdev))
358 hci_setup_sync(sco, acl->handle);
359 else
360 hci_add_sco(sco, acl->handle);
361 }
333 362
334 return sco; 363 return sco;
335} 364}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 2894382dd26d..372b0d3b75a8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1361,6 +1361,26 @@ static inline void hci_sched_sco(struct hci_dev *hdev)
1361 } 1361 }
1362} 1362}
1363 1363
1364static inline void hci_sched_esco(struct hci_dev *hdev)
1365{
1366 struct hci_conn *conn;
1367 struct sk_buff *skb;
1368 int quote;
1369
1370 BT_DBG("%s", hdev->name);
1371
1372 while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
1373 while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
1374 BT_DBG("skb %p len %d", skb, skb->len);
1375 hci_send_frame(skb);
1376
1377 conn->sent++;
1378 if (conn->sent == ~0)
1379 conn->sent = 0;
1380 }
1381 }
1382}
1383
1364static void hci_tx_task(unsigned long arg) 1384static void hci_tx_task(unsigned long arg)
1365{ 1385{
1366 struct hci_dev *hdev = (struct hci_dev *) arg; 1386 struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1376,6 +1396,8 @@ static void hci_tx_task(unsigned long arg)
1376 1396
1377 hci_sched_sco(hdev); 1397 hci_sched_sco(hdev);
1378 1398
1399 hci_sched_esco(hdev);
1400
1379 /* Send next queued raw (unknown type) packet */ 1401 /* Send next queued raw (unknown type) packet */
1380 while ((skb = skb_dequeue(&hdev->raw_q))) 1402 while ((skb = skb_dequeue(&hdev->raw_q)))
1381 hci_send_frame(skb); 1403 hci_send_frame(skb);
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)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 65b6fb1c4154..82d0dfdfa7e2 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -189,7 +189,7 @@ static int sco_connect(struct sock *sk)
189 struct sco_conn *conn; 189 struct sco_conn *conn;
190 struct hci_conn *hcon; 190 struct hci_conn *hcon;
191 struct hci_dev *hdev; 191 struct hci_dev *hdev;
192 int err = 0; 192 int err, type;
193 193
194 BT_DBG("%s -> %s", batostr(src), batostr(dst)); 194 BT_DBG("%s -> %s", batostr(src), batostr(dst));
195 195
@@ -200,7 +200,9 @@ static int sco_connect(struct sock *sk)
200 200
201 err = -ENOMEM; 201 err = -ENOMEM;
202 202
203 hcon = hci_connect(hdev, SCO_LINK, dst); 203 type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
204
205 hcon = hci_connect(hdev, type, dst);
204 if (!hcon) 206 if (!hcon)
205 goto done; 207 goto done;
206 208
@@ -224,6 +226,7 @@ static int sco_connect(struct sock *sk)
224 sk->sk_state = BT_CONNECT; 226 sk->sk_state = BT_CONNECT;
225 sco_sock_set_timer(sk, sk->sk_sndtimeo); 227 sco_sock_set_timer(sk, sk->sk_sndtimeo);
226 } 228 }
229
227done: 230done:
228 hci_dev_unlock_bh(hdev); 231 hci_dev_unlock_bh(hdev);
229 hci_dev_put(hdev); 232 hci_dev_put(hdev);
@@ -846,7 +849,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
846{ 849{
847 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); 850 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
848 851
849 if (hcon->type != SCO_LINK) 852 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
850 return 0; 853 return 0;
851 854
852 if (!status) { 855 if (!status) {
@@ -865,10 +868,11 @@ static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
865{ 868{
866 BT_DBG("hcon %p reason %d", hcon, reason); 869 BT_DBG("hcon %p reason %d", hcon, reason);
867 870
868 if (hcon->type != SCO_LINK) 871 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
869 return 0; 872 return 0;
870 873
871 sco_conn_del(hcon, bt_err(reason)); 874 sco_conn_del(hcon, bt_err(reason));
875
872 return 0; 876 return 0;
873} 877}
874 878