aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/bluetooth/hci_core.h
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-03-28 18:05:50 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-28 18:05:50 -0400
commitb0d44c0dbbd52effb731b1c0af9afd56215c48de (patch)
tree3237c0087d91a5390aed05689b9f610ba16fa116 /include/net/bluetooth/hci_core.h
parent9537a48ed4b9e4b738943d6da0a0fd4278adf905 (diff)
parent7c730ccdc1188b97f5c8cb690906242c7ed75c22 (diff)
Merge branch 'linus' into core/iommu
Conflicts: arch/x86/Kconfig
Diffstat (limited to 'include/net/bluetooth/hci_core.h')
-rw-r--r--include/net/bluetooth/hci_core.h84
1 files changed, 57 insertions, 27 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 46a43b721dd6..01f9316b4c23 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);
325void hci_conn_hash_flush(struct hci_dev *hdev); 326void hci_conn_hash_flush(struct hci_dev *hdev);
326void hci_conn_check_pending(struct hci_dev *hdev); 327void hci_conn_check_pending(struct hci_dev *hdev);
327 328
328struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); 329struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
329int hci_conn_check_link_mode(struct hci_conn *conn); 330int hci_conn_check_link_mode(struct hci_conn *conn);
330int hci_conn_auth(struct hci_conn *conn); 331int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
331int hci_conn_encrypt(struct hci_conn *conn);
332int hci_conn_change_link_key(struct hci_conn *conn); 332int hci_conn_change_link_key(struct hci_conn *conn);
333int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); 333int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
334 334
335void hci_conn_enter_active_mode(struct hci_conn *conn); 335void hci_conn_enter_active_mode(struct hci_conn *conn);
336void hci_conn_enter_sniff_mode(struct hci_conn *conn); 336void hci_conn_enter_sniff_mode(struct hci_conn *conn);
@@ -470,26 +470,26 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
470 470
471/* ----- HCI protocols ----- */ 471/* ----- HCI protocols ----- */
472struct hci_proto { 472struct 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);
482 int (*disconn_cfm) (struct hci_conn *conn, __u8 reason);
482 int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); 483 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); 484 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
484 int (*auth_cfm) (struct hci_conn *conn, __u8 status); 485 int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
485 int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
486}; 486};
487 487
488static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) 488static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
489{ 489{
490 register struct hci_proto *hp; 490 register struct hci_proto *hp;
491 int mask = 0; 491 int mask = 0;
492 492
493 hp = hci_proto[HCI_PROTO_L2CAP]; 493 hp = hci_proto[HCI_PROTO_L2CAP];
494 if (hp && hp->connect_ind) 494 if (hp && hp->connect_ind)
495 mask |= hp->connect_ind(hdev, bdaddr, type); 495 mask |= hp->connect_ind(hdev, bdaddr, type);
@@ -514,30 +514,52 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
514 hp->connect_cfm(conn, status); 514 hp->connect_cfm(conn, status);
515} 515}
516 516
517static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) 517static inline int hci_proto_disconn_ind(struct hci_conn *conn)
518{ 518{
519 register struct hci_proto *hp; 519 register struct hci_proto *hp;
520 int reason = 0x13;
520 521
521 hp = hci_proto[HCI_PROTO_L2CAP]; 522 hp = hci_proto[HCI_PROTO_L2CAP];
522 if (hp && hp->disconn_ind) 523 if (hp && hp->disconn_ind)
523 hp->disconn_ind(conn, reason); 524 reason = hp->disconn_ind(conn);
524 525
525 hp = hci_proto[HCI_PROTO_SCO]; 526 hp = hci_proto[HCI_PROTO_SCO];
526 if (hp && hp->disconn_ind) 527 if (hp && hp->disconn_ind)
527 hp->disconn_ind(conn, reason); 528 reason = hp->disconn_ind(conn);
529
530 return reason;
531}
532
533static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
534{
535 register struct hci_proto *hp;
536
537 hp = hci_proto[HCI_PROTO_L2CAP];
538 if (hp && hp->disconn_cfm)
539 hp->disconn_cfm(conn, reason);
540
541 hp = hci_proto[HCI_PROTO_SCO];
542 if (hp && hp->disconn_cfm)
543 hp->disconn_cfm(conn, reason);
528} 544}
529 545
530static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) 546static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
531{ 547{
532 register struct hci_proto *hp; 548 register struct hci_proto *hp;
549 __u8 encrypt;
550
551 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
552 return;
553
554 encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
533 555
534 hp = hci_proto[HCI_PROTO_L2CAP]; 556 hp = hci_proto[HCI_PROTO_L2CAP];
535 if (hp && hp->auth_cfm) 557 if (hp && hp->security_cfm)
536 hp->auth_cfm(conn, status); 558 hp->security_cfm(conn, status, encrypt);
537 559
538 hp = hci_proto[HCI_PROTO_SCO]; 560 hp = hci_proto[HCI_PROTO_SCO];
539 if (hp && hp->auth_cfm) 561 if (hp && hp->security_cfm)
540 hp->auth_cfm(conn, status); 562 hp->security_cfm(conn, status, encrypt);
541} 563}
542 564
543static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) 565static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
@@ -545,12 +567,12 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u
545 register struct hci_proto *hp; 567 register struct hci_proto *hp;
546 568
547 hp = hci_proto[HCI_PROTO_L2CAP]; 569 hp = hci_proto[HCI_PROTO_L2CAP];
548 if (hp && hp->encrypt_cfm) 570 if (hp && hp->security_cfm)
549 hp->encrypt_cfm(conn, status, encrypt); 571 hp->security_cfm(conn, status, encrypt);
550 572
551 hp = hci_proto[HCI_PROTO_SCO]; 573 hp = hci_proto[HCI_PROTO_SCO];
552 if (hp && hp->encrypt_cfm) 574 if (hp && hp->security_cfm)
553 hp->encrypt_cfm(conn, status, encrypt); 575 hp->security_cfm(conn, status, encrypt);
554} 576}
555 577
556int hci_register_proto(struct hci_proto *hproto); 578int hci_register_proto(struct hci_proto *hproto);
@@ -562,8 +584,7 @@ struct hci_cb {
562 584
563 char *name; 585 char *name;
564 586
565 void (*auth_cfm) (struct hci_conn *conn, __u8 status); 587 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); 588 void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
568 void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); 589 void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
569}; 590};
@@ -571,14 +592,20 @@ struct hci_cb {
571static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) 592static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
572{ 593{
573 struct list_head *p; 594 struct list_head *p;
595 __u8 encrypt;
574 596
575 hci_proto_auth_cfm(conn, status); 597 hci_proto_auth_cfm(conn, status);
576 598
599 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
600 return;
601
602 encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
603
577 read_lock_bh(&hci_cb_list_lock); 604 read_lock_bh(&hci_cb_list_lock);
578 list_for_each(p, &hci_cb_list) { 605 list_for_each(p, &hci_cb_list) {
579 struct hci_cb *cb = list_entry(p, struct hci_cb, list); 606 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
580 if (cb->auth_cfm) 607 if (cb->security_cfm)
581 cb->auth_cfm(conn, status); 608 cb->security_cfm(conn, status, encrypt);
582 } 609 }
583 read_unlock_bh(&hci_cb_list_lock); 610 read_unlock_bh(&hci_cb_list_lock);
584} 611}
@@ -587,13 +614,16 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
587{ 614{
588 struct list_head *p; 615 struct list_head *p;
589 616
617 if (conn->sec_level == BT_SECURITY_SDP)
618 conn->sec_level = BT_SECURITY_LOW;
619
590 hci_proto_encrypt_cfm(conn, status, encrypt); 620 hci_proto_encrypt_cfm(conn, status, encrypt);
591 621
592 read_lock_bh(&hci_cb_list_lock); 622 read_lock_bh(&hci_cb_list_lock);
593 list_for_each(p, &hci_cb_list) { 623 list_for_each(p, &hci_cb_list) {
594 struct hci_cb *cb = list_entry(p, struct hci_cb, list); 624 struct hci_cb *cb = list_entry(p, struct hci_cb, list);
595 if (cb->encrypt_cfm) 625 if (cb->security_cfm)
596 cb->encrypt_cfm(conn, status, encrypt); 626 cb->security_cfm(conn, status, encrypt);
597 } 627 }
598 read_unlock_bh(&hci_cb_list_lock); 628 read_unlock_bh(&hci_cb_list_lock);
599} 629}