hci_conn.c (5a2dd72abdae75ea2960145e0549635ce4e0be96) | hci_conn.c (8c1b235594fbab9a13240a1dac12ea9fd99b6440) |
---|---|
1/* 2 BlueZ - Bluetooth protocol stack for Linux 3 Copyright (C) 2000-2001 Qualcomm Incorporated 4 5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License version 2 as --- 311 unchanged lines hidden (view full) --- 320 321 read_unlock_bh(&hci_dev_list_lock); 322 return hdev; 323} 324EXPORT_SYMBOL(hci_get_route); 325 326/* Create SCO or ACL connection. 327 * Device _must_ be locked */ | 1/* 2 BlueZ - Bluetooth protocol stack for Linux 3 Copyright (C) 2000-2001 Qualcomm Incorporated 4 5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License version 2 as --- 311 unchanged lines hidden (view full) --- 320 321 read_unlock_bh(&hci_dev_list_lock); 322 return hdev; 323} 324EXPORT_SYMBOL(hci_get_route); 325 326/* Create SCO or ACL connection. 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{ 330 struct hci_conn *acl; 331 struct hci_conn *sco; 332 333 BT_DBG("%s dst %s", hdev->name, batostr(dst)); 334 335 if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) { 336 if (!(acl = hci_conn_add(hdev, ACL_LINK, dst))) 337 return NULL; 338 } 339 340 hci_conn_hold(acl); 341 342 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { | 329{ 330 struct hci_conn *acl; 331 struct hci_conn *sco; 332 333 BT_DBG("%s dst %s", hdev->name, batostr(dst)); 334 335 if (!(acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst))) { 336 if (!(acl = hci_conn_add(hdev, ACL_LINK, dst))) 337 return NULL; 338 } 339 340 hci_conn_hold(acl); 341 342 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { |
343 acl->sec_level = sec_level; |
|
343 acl->auth_type = auth_type; 344 hci_acl_connect(acl); 345 } 346 347 if (type == ACL_LINK) 348 return acl; 349 350 if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) { --- 29 unchanged lines hidden (view full) --- 380 !(conn->link_mode & HCI_LM_ENCRYPT)) 381 return 0; 382 383 return 1; 384} 385EXPORT_SYMBOL(hci_conn_check_link_mode); 386 387/* Authenticate remote device */ | 344 acl->auth_type = auth_type; 345 hci_acl_connect(acl); 346 } 347 348 if (type == ACL_LINK) 349 return acl; 350 351 if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) { --- 29 unchanged lines hidden (view full) --- 381 !(conn->link_mode & HCI_LM_ENCRYPT)) 382 return 0; 383 384 return 1; 385} 386EXPORT_SYMBOL(hci_conn_check_link_mode); 387 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 BT_DBG("conn %p", conn); 391 | 390{ 391 BT_DBG("conn %p", conn); 392 |
392 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { 393 if (!(conn->auth_type & 0x01)) { 394 conn->auth_type |= 0x01; 395 conn->link_mode &= ~HCI_LM_AUTH; 396 } 397 } | 393 if (sec_level > conn->sec_level) 394 conn->link_mode &= ~HCI_LM_AUTH; |
398 | 395 |
396 conn->sec_level = sec_level; 397 398 if (sec_level == BT_SECURITY_HIGH) 399 conn->auth_type |= 0x01; 400 |
|
399 if (conn->link_mode & HCI_LM_AUTH) 400 return 1; 401 402 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 403 struct hci_cp_auth_requested cp; 404 cp.handle = cpu_to_le16(conn->handle); 405 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, 406 sizeof(cp), &cp); 407 } | 401 if (conn->link_mode & HCI_LM_AUTH) 402 return 1; 403 404 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 405 struct hci_cp_auth_requested cp; 406 cp.handle = cpu_to_le16(conn->handle); 407 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, 408 sizeof(cp), &cp); 409 } |
410 |
|
408 return 0; 409} | 411 return 0; 412} |
410EXPORT_SYMBOL(hci_conn_auth); | |
411 | 413 |
412/* Enable encryption */ 413int hci_conn_encrypt(struct hci_conn *conn) | 414/* Enable security */ 415int hci_conn_security(struct hci_conn *conn, __u8 sec_level) |
414{ 415 BT_DBG("conn %p", conn); 416 | 416{ 417 BT_DBG("conn %p", conn); 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 420 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 421 return 0; 422 | 431 432 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 433 return 0; 434 |
423 if (hci_conn_auth(conn)) { | 435 if (hci_conn_auth(conn, sec_level)) { |
424 struct hci_cp_set_conn_encrypt cp; 425 cp.handle = cpu_to_le16(conn->handle); 426 cp.encrypt = 1; 427 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, 428 sizeof(cp), &cp); 429 } | 436 struct hci_cp_set_conn_encrypt cp; 437 cp.handle = cpu_to_le16(conn->handle); 438 cp.encrypt = 1; 439 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, 440 sizeof(cp), &cp); 441 } |
442 |
|
430 return 0; 431} | 443 return 0; 444} |
432EXPORT_SYMBOL(hci_conn_encrypt); | 445EXPORT_SYMBOL(hci_conn_security); |
433 434/* Change link key */ 435int hci_conn_change_link_key(struct hci_conn *conn) 436{ 437 BT_DBG("conn %p", conn); 438 439 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 440 struct hci_cp_change_conn_link_key cp; 441 cp.handle = cpu_to_le16(conn->handle); 442 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, 443 sizeof(cp), &cp); 444 } | 446 447/* Change link key */ 448int hci_conn_change_link_key(struct hci_conn *conn) 449{ 450 BT_DBG("conn %p", conn); 451 452 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 453 struct hci_cp_change_conn_link_key cp; 454 cp.handle = cpu_to_le16(conn->handle); 455 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, 456 sizeof(cp), &cp); 457 } |
458 |
|
445 return 0; 446} 447EXPORT_SYMBOL(hci_conn_change_link_key); 448 449/* Switch role */ | 459 return 0; 460} 461EXPORT_SYMBOL(hci_conn_change_link_key); 462 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{ 452 BT_DBG("conn %p", conn); 453 454 if (!role && conn->link_mode & HCI_LM_MASTER) 455 return 1; 456 457 if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) { 458 struct hci_cp_switch_role cp; 459 bacpy(&cp.bdaddr, &conn->dst); 460 cp.role = role; 461 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); 462 } | 465{ 466 BT_DBG("conn %p", conn); 467 468 if (!role && conn->link_mode & HCI_LM_MASTER) 469 return 1; 470 471 if (!test_and_set_bit(HCI_CONN_RSWITCH_PEND, &conn->pend)) { 472 struct hci_cp_switch_role cp; 473 bacpy(&cp.bdaddr, &conn->dst); 474 cp.role = role; 475 hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); 476 } |
477 |
|
463 return 0; 464} 465EXPORT_SYMBOL(hci_conn_switch_role); 466 467/* Enter active mode */ 468void hci_conn_enter_active_mode(struct hci_conn *conn) 469{ 470 struct hci_dev *hdev = conn->hdev; --- 198 unchanged lines hidden --- | 478 return 0; 479} 480EXPORT_SYMBOL(hci_conn_switch_role); 481 482/* Enter active mode */ 483void hci_conn_enter_active_mode(struct hci_conn *conn) 484{ 485 struct hci_dev *hdev = conn->hdev; --- 198 unchanged lines hidden --- |