diff options
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 9 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 56 |
2 files changed, 42 insertions, 23 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 847e9e6df08b..3ad5390a4dd5 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -53,6 +53,15 @@ | |||
53 | #define SOL_SCO 17 | 53 | #define SOL_SCO 17 |
54 | #define SOL_RFCOMM 18 | 54 | #define SOL_RFCOMM 18 |
55 | 55 | ||
56 | #define BT_SECURITY 4 | ||
57 | struct bt_security { | ||
58 | __u8 level; | ||
59 | }; | ||
60 | #define BT_SECURITY_SDP 0 | ||
61 | #define BT_SECURITY_LOW 1 | ||
62 | #define BT_SECURITY_MEDIUM 2 | ||
63 | #define BT_SECURITY_HIGH 3 | ||
64 | |||
56 | #define BT_DEFER_SETUP 7 | 65 | #define BT_DEFER_SETUP 7 |
57 | 66 | ||
58 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | 67 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 46a43b721dd6..4b14972c1694 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -169,6 +169,7 @@ struct hci_conn { | |||
169 | __u16 link_policy; | 169 | __u16 link_policy; |
170 | __u32 link_mode; | 170 | __u32 link_mode; |
171 | __u8 auth_type; | 171 | __u8 auth_type; |
172 | __u8 sec_level; | ||
172 | __u8 power_save; | 173 | __u8 power_save; |
173 | unsigned long pend; | 174 | unsigned long pend; |
174 | 175 | ||
@@ -325,12 +326,11 @@ int hci_conn_del(struct hci_conn *conn); | |||
325 | void hci_conn_hash_flush(struct hci_dev *hdev); | 326 | void hci_conn_hash_flush(struct hci_dev *hdev); |
326 | void hci_conn_check_pending(struct hci_dev *hdev); | 327 | void hci_conn_check_pending(struct hci_dev *hdev); |
327 | 328 | ||
328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); | 329 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); |
329 | int hci_conn_check_link_mode(struct hci_conn *conn); | 330 | int hci_conn_check_link_mode(struct hci_conn *conn); |
330 | int hci_conn_auth(struct hci_conn *conn); | 331 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level); |
331 | int hci_conn_encrypt(struct hci_conn *conn); | ||
332 | int hci_conn_change_link_key(struct hci_conn *conn); | 332 | int hci_conn_change_link_key(struct hci_conn *conn); |
333 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); | 333 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); |
334 | 334 | ||
335 | void hci_conn_enter_active_mode(struct hci_conn *conn); | 335 | void hci_conn_enter_active_mode(struct hci_conn *conn); |
336 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); | 336 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); |
@@ -470,26 +470,25 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
470 | 470 | ||
471 | /* ----- HCI protocols ----- */ | 471 | /* ----- HCI protocols ----- */ |
472 | struct hci_proto { | 472 | struct hci_proto { |
473 | char *name; | 473 | char *name; |
474 | unsigned int id; | 474 | unsigned int id; |
475 | unsigned long flags; | 475 | unsigned long flags; |
476 | 476 | ||
477 | void *priv; | 477 | void *priv; |
478 | 478 | ||
479 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); | 479 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); |
480 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); | 480 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); |
481 | int (*disconn_ind) (struct hci_conn *conn, __u8 reason); | 481 | int (*disconn_ind) (struct hci_conn *conn, __u8 reason); |
482 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | 482 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); |
483 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); | 483 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); |
484 | int (*auth_cfm) (struct hci_conn *conn, __u8 status); | 484 | int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); |
485 | int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | ||
486 | }; | 485 | }; |
487 | 486 | ||
488 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 487 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) |
489 | { | 488 | { |
490 | register struct hci_proto *hp; | 489 | register struct hci_proto *hp; |
491 | int mask = 0; | 490 | int mask = 0; |
492 | 491 | ||
493 | hp = hci_proto[HCI_PROTO_L2CAP]; | 492 | hp = hci_proto[HCI_PROTO_L2CAP]; |
494 | if (hp && hp->connect_ind) | 493 | if (hp && hp->connect_ind) |
495 | mask |= hp->connect_ind(hdev, bdaddr, type); | 494 | mask |= hp->connect_ind(hdev, bdaddr, type); |
@@ -530,14 +529,20 @@ static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) | |||
530 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | 529 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) |
531 | { | 530 | { |
532 | register struct hci_proto *hp; | 531 | register struct hci_proto *hp; |
532 | __u8 encrypt; | ||
533 | |||
534 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | ||
535 | return; | ||
536 | |||
537 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | ||
533 | 538 | ||
534 | hp = hci_proto[HCI_PROTO_L2CAP]; | 539 | hp = hci_proto[HCI_PROTO_L2CAP]; |
535 | if (hp && hp->auth_cfm) | 540 | if (hp && hp->security_cfm) |
536 | hp->auth_cfm(conn, status); | 541 | hp->security_cfm(conn, status, encrypt); |
537 | 542 | ||
538 | hp = hci_proto[HCI_PROTO_SCO]; | 543 | hp = hci_proto[HCI_PROTO_SCO]; |
539 | if (hp && hp->auth_cfm) | 544 | if (hp && hp->security_cfm) |
540 | hp->auth_cfm(conn, status); | 545 | hp->security_cfm(conn, status, encrypt); |
541 | } | 546 | } |
542 | 547 | ||
543 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | 548 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) |
@@ -545,12 +550,12 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u | |||
545 | register struct hci_proto *hp; | 550 | register struct hci_proto *hp; |
546 | 551 | ||
547 | hp = hci_proto[HCI_PROTO_L2CAP]; | 552 | hp = hci_proto[HCI_PROTO_L2CAP]; |
548 | if (hp && hp->encrypt_cfm) | 553 | if (hp && hp->security_cfm) |
549 | hp->encrypt_cfm(conn, status, encrypt); | 554 | hp->security_cfm(conn, status, encrypt); |
550 | 555 | ||
551 | hp = hci_proto[HCI_PROTO_SCO]; | 556 | hp = hci_proto[HCI_PROTO_SCO]; |
552 | if (hp && hp->encrypt_cfm) | 557 | if (hp && hp->security_cfm) |
553 | hp->encrypt_cfm(conn, status, encrypt); | 558 | hp->security_cfm(conn, status, encrypt); |
554 | } | 559 | } |
555 | 560 | ||
556 | int hci_register_proto(struct hci_proto *hproto); | 561 | int hci_register_proto(struct hci_proto *hproto); |
@@ -562,8 +567,7 @@ struct hci_cb { | |||
562 | 567 | ||
563 | char *name; | 568 | char *name; |
564 | 569 | ||
565 | void (*auth_cfm) (struct hci_conn *conn, __u8 status); | 570 | void (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); |
566 | void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | ||
567 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); | 571 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); |
568 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); | 572 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); |
569 | }; | 573 | }; |
@@ -571,14 +575,20 @@ struct hci_cb { | |||
571 | static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) | 575 | static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) |
572 | { | 576 | { |
573 | struct list_head *p; | 577 | struct list_head *p; |
578 | __u8 encrypt; | ||
574 | 579 | ||
575 | hci_proto_auth_cfm(conn, status); | 580 | hci_proto_auth_cfm(conn, status); |
576 | 581 | ||
582 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | ||
583 | return; | ||
584 | |||
585 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | ||
586 | |||
577 | read_lock_bh(&hci_cb_list_lock); | 587 | read_lock_bh(&hci_cb_list_lock); |
578 | list_for_each(p, &hci_cb_list) { | 588 | list_for_each(p, &hci_cb_list) { |
579 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 589 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
580 | if (cb->auth_cfm) | 590 | if (cb->security_cfm) |
581 | cb->auth_cfm(conn, status); | 591 | cb->security_cfm(conn, status, encrypt); |
582 | } | 592 | } |
583 | read_unlock_bh(&hci_cb_list_lock); | 593 | read_unlock_bh(&hci_cb_list_lock); |
584 | } | 594 | } |
@@ -592,8 +602,8 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr | |||
592 | read_lock_bh(&hci_cb_list_lock); | 602 | read_lock_bh(&hci_cb_list_lock); |
593 | list_for_each(p, &hci_cb_list) { | 603 | list_for_each(p, &hci_cb_list) { |
594 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 604 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
595 | if (cb->encrypt_cfm) | 605 | if (cb->security_cfm) |
596 | cb->encrypt_cfm(conn, status, encrypt); | 606 | cb->security_cfm(conn, status, encrypt); |
597 | } | 607 | } |
598 | read_unlock_bh(&hci_cb_list_lock); | 608 | read_unlock_bh(&hci_cb_list_lock); |
599 | } | 609 | } |