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.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a4a789f24c8d..98f97a1e9bbb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -325,7 +325,7 @@ EXPORT_SYMBOL(hci_get_route);
325 325
326/* Create SCO or ACL connection. 326/* Create SCO or ACL connection.
327 * Device _must_ be locked */ 327 * Device _must_ be locked */
328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type) 328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type)
329{ 329{
330 struct hci_conn *acl; 330 struct hci_conn *acl;
331 struct hci_conn *sco; 331 struct hci_conn *sco;
@@ -340,6 +340,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
340 hci_conn_hold(acl); 340 hci_conn_hold(acl);
341 341
342 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { 342 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
343 acl->sec_level = sec_level;
343 acl->auth_type = auth_type; 344 acl->auth_type = auth_type;
344 hci_acl_connect(acl); 345 hci_acl_connect(acl);
345 } 346 }
@@ -385,16 +386,17 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
385EXPORT_SYMBOL(hci_conn_check_link_mode); 386EXPORT_SYMBOL(hci_conn_check_link_mode);
386 387
387/* Authenticate remote device */ 388/* Authenticate remote device */
388int hci_conn_auth(struct hci_conn *conn) 389static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
389{ 390{
390 BT_DBG("conn %p", conn); 391 BT_DBG("conn %p", conn);
391 392
392 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { 393 if (sec_level > conn->sec_level)
393 if (!(conn->auth_type & 0x01)) { 394 conn->link_mode &= ~HCI_LM_AUTH;
394 conn->auth_type |= 0x01; 395
395 conn->link_mode &= ~HCI_LM_AUTH; 396 conn->sec_level = sec_level;
396 } 397
397 } 398 if (sec_level == BT_SECURITY_HIGH)
399 conn->auth_type |= 0x01;
398 400
399 if (conn->link_mode & HCI_LM_AUTH) 401 if (conn->link_mode & HCI_LM_AUTH)
400 return 1; 402 return 1;
@@ -405,31 +407,42 @@ int hci_conn_auth(struct hci_conn *conn)
405 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, 407 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
406 sizeof(cp), &cp); 408 sizeof(cp), &cp);
407 } 409 }
410
408 return 0; 411 return 0;
409} 412}
410EXPORT_SYMBOL(hci_conn_auth);
411 413
412/* Enable encryption */ 414/* Enable security */
413int hci_conn_encrypt(struct hci_conn *conn) 415int hci_conn_security(struct hci_conn *conn, __u8 sec_level)
414{ 416{
415 BT_DBG("conn %p", conn); 417 BT_DBG("conn %p", conn);
416 418
419 if (sec_level == BT_SECURITY_SDP)
420 return 1;
421
422 if (sec_level == BT_SECURITY_LOW) {
423 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
424 return hci_conn_auth(conn, sec_level);
425 else
426 return 1;
427 }
428
417 if (conn->link_mode & HCI_LM_ENCRYPT) 429 if (conn->link_mode & HCI_LM_ENCRYPT)
418 return hci_conn_auth(conn); 430 return hci_conn_auth(conn, sec_level);
419 431
420 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 432 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
421 return 0; 433 return 0;
422 434
423 if (hci_conn_auth(conn)) { 435 if (hci_conn_auth(conn, sec_level)) {
424 struct hci_cp_set_conn_encrypt cp; 436 struct hci_cp_set_conn_encrypt cp;
425 cp.handle = cpu_to_le16(conn->handle); 437 cp.handle = cpu_to_le16(conn->handle);
426 cp.encrypt = 1; 438 cp.encrypt = 1;
427 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, 439 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
428 sizeof(cp), &cp); 440 sizeof(cp), &cp);
429 } 441 }
442
430 return 0; 443 return 0;
431} 444}
432EXPORT_SYMBOL(hci_conn_encrypt); 445EXPORT_SYMBOL(hci_conn_security);
433 446
434/* Change link key */ 447/* Change link key */
435int hci_conn_change_link_key(struct hci_conn *conn) 448int hci_conn_change_link_key(struct hci_conn *conn)
@@ -442,12 +455,13 @@ int hci_conn_change_link_key(struct hci_conn *conn)
442 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, 455 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
443 sizeof(cp), &cp); 456 sizeof(cp), &cp);
444 } 457 }
458
445 return 0; 459 return 0;
446} 460}
447EXPORT_SYMBOL(hci_conn_change_link_key); 461EXPORT_SYMBOL(hci_conn_change_link_key);
448 462
449/* Switch role */ 463/* Switch role */
450int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) 464int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
451{ 465{
452 BT_DBG("conn %p", conn); 466 BT_DBG("conn %p", conn);
453 467
@@ -460,6 +474,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
460 cp.role = role; 474 cp.role = role;
461 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); 475 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
462 } 476 }
477
463 return 0; 478 return 0;
464} 479}
465EXPORT_SYMBOL(hci_conn_switch_role); 480EXPORT_SYMBOL(hci_conn_switch_role);