diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 82 |
1 files changed, 61 insertions, 21 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5fdfc9a67d39..9483320f6dad 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -78,11 +78,11 @@ 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, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); | 85 | hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void hci_acl_connect_cancel(struct hci_conn *conn) | 88 | static void hci_acl_connect_cancel(struct hci_conn *conn) |
@@ -95,8 +95,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn) | |||
95 | return; | 95 | return; |
96 | 96 | ||
97 | bacpy(&cp.bdaddr, &conn->dst); | 97 | bacpy(&cp.bdaddr, &conn->dst); |
98 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | 98 | hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); |
99 | OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp); | ||
100 | } | 99 | } |
101 | 100 | ||
102 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | 101 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason) |
@@ -109,8 +108,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | |||
109 | 108 | ||
110 | cp.handle = cpu_to_le16(conn->handle); | 109 | cp.handle = cpu_to_le16(conn->handle); |
111 | cp.reason = reason; | 110 | cp.reason = reason; |
112 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | 111 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); |
113 | OCF_DISCONNECT, sizeof(cp), &cp); | ||
114 | } | 112 | } |
115 | 113 | ||
116 | void hci_add_sco(struct hci_conn *conn, __u16 handle) | 114 | void hci_add_sco(struct hci_conn *conn, __u16 handle) |
@@ -126,7 +124,29 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle) | |||
126 | cp.handle = cpu_to_le16(handle); | 124 | cp.handle = cpu_to_le16(handle); |
127 | cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 125 | cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); |
128 | 126 | ||
129 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp); | 127 | hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); |
128 | } | ||
129 | |||
130 | void 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); | ||
130 | } | 150 | } |
131 | 151 | ||
132 | static void hci_conn_timeout(unsigned long arg) | 152 | static void hci_conn_timeout(unsigned long arg) |
@@ -143,7 +163,10 @@ static void hci_conn_timeout(unsigned long arg) | |||
143 | 163 | ||
144 | switch (conn->state) { | 164 | switch (conn->state) { |
145 | case BT_CONNECT: | 165 | case BT_CONNECT: |
146 | 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); | ||
147 | break; | 170 | break; |
148 | case BT_CONNECTED: | 171 | case BT_CONNECTED: |
149 | hci_acl_disconn(conn, 0x13); | 172 | hci_acl_disconn(conn, 0x13); |
@@ -330,8 +353,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
330 | hci_conn_hold(sco); | 353 | hci_conn_hold(sco); |
331 | 354 | ||
332 | if (acl->state == BT_CONNECTED && | 355 | if (acl->state == BT_CONNECTED && |
333 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) | 356 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { |
334 | 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 | } | ||
335 | 362 | ||
336 | return sco; | 363 | return sco; |
337 | } | 364 | } |
@@ -348,7 +375,7 @@ int hci_conn_auth(struct hci_conn *conn) | |||
348 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 375 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
349 | struct hci_cp_auth_requested cp; | 376 | struct hci_cp_auth_requested cp; |
350 | cp.handle = cpu_to_le16(conn->handle); | 377 | cp.handle = cpu_to_le16(conn->handle); |
351 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED, sizeof(cp), &cp); | 378 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); |
352 | } | 379 | } |
353 | return 0; | 380 | return 0; |
354 | } | 381 | } |
@@ -369,7 +396,7 @@ int hci_conn_encrypt(struct hci_conn *conn) | |||
369 | struct hci_cp_set_conn_encrypt cp; | 396 | struct hci_cp_set_conn_encrypt cp; |
370 | cp.handle = cpu_to_le16(conn->handle); | 397 | cp.handle = cpu_to_le16(conn->handle); |
371 | cp.encrypt = 1; | 398 | cp.encrypt = 1; |
372 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp); | 399 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); |
373 | } | 400 | } |
374 | return 0; | 401 | return 0; |
375 | } | 402 | } |
@@ -383,7 +410,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) | |||
383 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 410 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
384 | struct hci_cp_change_conn_link_key cp; | 411 | struct hci_cp_change_conn_link_key cp; |
385 | cp.handle = cpu_to_le16(conn->handle); | 412 | cp.handle = cpu_to_le16(conn->handle); |
386 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); | 413 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); |
387 | } | 414 | } |
388 | return 0; | 415 | return 0; |
389 | } | 416 | } |
@@ -401,7 +428,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) | |||
401 | struct hci_cp_switch_role cp; | 428 | struct hci_cp_switch_role cp; |
402 | bacpy(&cp.bdaddr, &conn->dst); | 429 | bacpy(&cp.bdaddr, &conn->dst); |
403 | cp.role = role; | 430 | cp.role = role; |
404 | hci_send_cmd(conn->hdev, OGF_LINK_POLICY, OCF_SWITCH_ROLE, sizeof(cp), &cp); | 431 | hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); |
405 | } | 432 | } |
406 | return 0; | 433 | return 0; |
407 | } | 434 | } |
@@ -423,8 +450,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn) | |||
423 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | 450 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { |
424 | struct hci_cp_exit_sniff_mode cp; | 451 | struct hci_cp_exit_sniff_mode cp; |
425 | cp.handle = cpu_to_le16(conn->handle); | 452 | cp.handle = cpu_to_le16(conn->handle); |
426 | hci_send_cmd(hdev, OGF_LINK_POLICY, | 453 | hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp); |
427 | OCF_EXIT_SNIFF_MODE, sizeof(cp), &cp); | ||
428 | } | 454 | } |
429 | 455 | ||
430 | timer: | 456 | timer: |
@@ -455,8 +481,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn) | |||
455 | cp.max_latency = cpu_to_le16(0); | 481 | cp.max_latency = cpu_to_le16(0); |
456 | cp.min_remote_timeout = cpu_to_le16(0); | 482 | cp.min_remote_timeout = cpu_to_le16(0); |
457 | cp.min_local_timeout = cpu_to_le16(0); | 483 | cp.min_local_timeout = cpu_to_le16(0); |
458 | hci_send_cmd(hdev, OGF_LINK_POLICY, | 484 | hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); |
459 | OCF_SNIFF_SUBRATE, sizeof(cp), &cp); | ||
460 | } | 485 | } |
461 | 486 | ||
462 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | 487 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { |
@@ -466,8 +491,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn) | |||
466 | cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); | 491 | cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); |
467 | cp.attempt = cpu_to_le16(4); | 492 | cp.attempt = cpu_to_le16(4); |
468 | cp.timeout = cpu_to_le16(1); | 493 | cp.timeout = cpu_to_le16(1); |
469 | hci_send_cmd(hdev, OGF_LINK_POLICY, | 494 | hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); |
470 | OCF_SNIFF_MODE, sizeof(cp), &cp); | ||
471 | } | 495 | } |
472 | } | 496 | } |
473 | 497 | ||
@@ -493,6 +517,22 @@ void hci_conn_hash_flush(struct hci_dev *hdev) | |||
493 | } | 517 | } |
494 | } | 518 | } |
495 | 519 | ||
520 | /* Check pending connect attempts */ | ||
521 | void hci_conn_check_pending(struct hci_dev *hdev) | ||
522 | { | ||
523 | struct hci_conn *conn; | ||
524 | |||
525 | BT_DBG("hdev %s", hdev->name); | ||
526 | |||
527 | hci_dev_lock(hdev); | ||
528 | |||
529 | conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
530 | if (conn) | ||
531 | hci_acl_connect(conn); | ||
532 | |||
533 | hci_dev_unlock(hdev); | ||
534 | } | ||
535 | |||
496 | int hci_get_conn_list(void __user *arg) | 536 | int hci_get_conn_list(void __user *arg) |
497 | { | 537 | { |
498 | struct hci_conn_list_req req, *cl; | 538 | struct hci_conn_list_req req, *cl; |