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 ---