aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a4a789f24c8d..1181db08d9de 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -123,6 +123,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
123 conn->state = BT_CONNECT; 123 conn->state = BT_CONNECT;
124 conn->out = 1; 124 conn->out = 1;
125 125
126 conn->attempt++;
127
126 cp.handle = cpu_to_le16(handle); 128 cp.handle = cpu_to_le16(handle);
127 cp.pkt_type = cpu_to_le16(conn->pkt_type); 129 cp.pkt_type = cpu_to_le16(conn->pkt_type);
128 130
@@ -139,6 +141,8 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
139 conn->state = BT_CONNECT; 141 conn->state = BT_CONNECT;
140 conn->out = 1; 142 conn->out = 1;
141 143
144 conn->attempt++;
145
142 cp.handle = cpu_to_le16(handle); 146 cp.handle = cpu_to_le16(handle);
143 cp.pkt_type = cpu_to_le16(conn->pkt_type); 147 cp.pkt_type = cpu_to_le16(conn->pkt_type);
144 148
@@ -155,6 +159,7 @@ static void hci_conn_timeout(unsigned long arg)
155{ 159{
156 struct hci_conn *conn = (void *) arg; 160 struct hci_conn *conn = (void *) arg;
157 struct hci_dev *hdev = conn->hdev; 161 struct hci_dev *hdev = conn->hdev;
162 __u8 reason;
158 163
159 BT_DBG("conn %p state %d", conn, conn->state); 164 BT_DBG("conn %p state %d", conn, conn->state);
160 165
@@ -173,7 +178,8 @@ static void hci_conn_timeout(unsigned long arg)
173 break; 178 break;
174 case BT_CONFIG: 179 case BT_CONFIG:
175 case BT_CONNECTED: 180 case BT_CONNECTED:
176 hci_acl_disconn(conn, 0x13); 181 reason = hci_proto_disconn_ind(conn);
182 hci_acl_disconn(conn, reason);
177 break; 183 break;
178 default: 184 default:
179 conn->state = BT_CLOSED; 185 conn->state = BT_CLOSED;
@@ -216,12 +222,13 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
216 break; 222 break;
217 case SCO_LINK: 223 case SCO_LINK:
218 if (lmp_esco_capable(hdev)) 224 if (lmp_esco_capable(hdev))
219 conn->pkt_type = hdev->esco_type & SCO_ESCO_MASK; 225 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
226 (hdev->esco_type & EDR_ESCO_MASK);
220 else 227 else
221 conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK; 228 conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
222 break; 229 break;
223 case ESCO_LINK: 230 case ESCO_LINK:
224 conn->pkt_type = hdev->esco_type; 231 conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
225 break; 232 break;
226 } 233 }
227 234
@@ -280,6 +287,8 @@ int hci_conn_del(struct hci_conn *conn)
280 287
281 skb_queue_purge(&conn->data_q); 288 skb_queue_purge(&conn->data_q);
282 289
290 hci_conn_del_sysfs(conn);
291
283 return 0; 292 return 0;
284} 293}
285 294
@@ -325,7 +334,7 @@ EXPORT_SYMBOL(hci_get_route);
325 334
326/* Create SCO or ACL connection. 335/* Create SCO or ACL connection.
327 * Device _must_ be locked */ 336 * Device _must_ be locked */
328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type) 337struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
329{ 338{
330 struct hci_conn *acl; 339 struct hci_conn *acl;
331 struct hci_conn *sco; 340 struct hci_conn *sco;
@@ -340,6 +349,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
340 hci_conn_hold(acl); 349 hci_conn_hold(acl);
341 350
342 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { 351 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
352 acl->sec_level = sec_level;
343 acl->auth_type = auth_type; 353 acl->auth_type = auth_type;
344 hci_acl_connect(acl); 354 hci_acl_connect(acl);
345 } 355 }
@@ -385,51 +395,59 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
385EXPORT_SYMBOL(hci_conn_check_link_mode); 395EXPORT_SYMBOL(hci_conn_check_link_mode);
386 396
387/* Authenticate remote device */ 397/* Authenticate remote device */
388int hci_conn_auth(struct hci_conn *conn) 398static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
389{ 399{
390 BT_DBG("conn %p", conn); 400 BT_DBG("conn %p", conn);
391 401
392 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { 402 if (sec_level > conn->sec_level)
393 if (!(conn->auth_type & 0x01)) { 403 conn->sec_level = sec_level;
394 conn->auth_type |= 0x01; 404 else if (conn->link_mode & HCI_LM_AUTH)
395 conn->link_mode &= ~HCI_LM_AUTH;
396 }
397 }
398
399 if (conn->link_mode & HCI_LM_AUTH)
400 return 1; 405 return 1;
401 406
407 conn->auth_type = auth_type;
408
402 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 409 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
403 struct hci_cp_auth_requested cp; 410 struct hci_cp_auth_requested cp;
404 cp.handle = cpu_to_le16(conn->handle); 411 cp.handle = cpu_to_le16(conn->handle);
405 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, 412 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
406 sizeof(cp), &cp); 413 sizeof(cp), &cp);
407 } 414 }
415
408 return 0; 416 return 0;
409} 417}
410EXPORT_SYMBOL(hci_conn_auth);
411 418
412/* Enable encryption */ 419/* Enable security */
413int hci_conn_encrypt(struct hci_conn *conn) 420int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
414{ 421{
415 BT_DBG("conn %p", conn); 422 BT_DBG("conn %p", conn);
416 423
424 if (sec_level == BT_SECURITY_SDP)
425 return 1;
426
427 if (sec_level == BT_SECURITY_LOW) {
428 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
429 return hci_conn_auth(conn, sec_level, auth_type);
430 else
431 return 1;
432 }
433
417 if (conn->link_mode & HCI_LM_ENCRYPT) 434 if (conn->link_mode & HCI_LM_ENCRYPT)
418 return hci_conn_auth(conn); 435 return hci_conn_auth(conn, sec_level, auth_type);
419 436
420 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 437 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
421 return 0; 438 return 0;
422 439
423 if (hci_conn_auth(conn)) { 440 if (hci_conn_auth(conn, sec_level, auth_type)) {
424 struct hci_cp_set_conn_encrypt cp; 441 struct hci_cp_set_conn_encrypt cp;
425 cp.handle = cpu_to_le16(conn->handle); 442 cp.handle = cpu_to_le16(conn->handle);
426 cp.encrypt = 1; 443 cp.encrypt = 1;
427 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, 444 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
428 sizeof(cp), &cp); 445 sizeof(cp), &cp);
429 } 446 }
447
430 return 0; 448 return 0;
431} 449}
432EXPORT_SYMBOL(hci_conn_encrypt); 450EXPORT_SYMBOL(hci_conn_security);
433 451
434/* Change link key */ 452/* Change link key */
435int hci_conn_change_link_key(struct hci_conn *conn) 453int hci_conn_change_link_key(struct hci_conn *conn)
@@ -442,12 +460,13 @@ int hci_conn_change_link_key(struct hci_conn *conn)
442 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, 460 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
443 sizeof(cp), &cp); 461 sizeof(cp), &cp);
444 } 462 }
463
445 return 0; 464 return 0;
446} 465}
447EXPORT_SYMBOL(hci_conn_change_link_key); 466EXPORT_SYMBOL(hci_conn_change_link_key);
448 467
449/* Switch role */ 468/* Switch role */
450int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) 469int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
451{ 470{
452 BT_DBG("conn %p", conn); 471 BT_DBG("conn %p", conn);
453 472
@@ -460,6 +479,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
460 cp.role = role; 479 cp.role = role;
461 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); 480 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
462 } 481 }
482
463 return 0; 483 return 0;
464} 484}
465EXPORT_SYMBOL(hci_conn_switch_role); 485EXPORT_SYMBOL(hci_conn_switch_role);
@@ -542,9 +562,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
542 562
543 c->state = BT_CLOSED; 563 c->state = BT_CLOSED;
544 564
545 hci_conn_del_sysfs(c); 565 hci_proto_disconn_cfm(c, 0x16);
546
547 hci_proto_disconn_ind(c, 0x16);
548 hci_conn_del(c); 566 hci_conn_del(c);
549 } 567 }
550} 568}