summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/net/bluetooth/bluetooth.h9
-rw-r--r--include/net/bluetooth/hci_core.h56
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 @@
#define SOL_SCO 17
#define SOL_RFCOMM 18
+#define BT_SECURITY 4
+struct bt_security {
+ __u8 level;
+};
+#define BT_SECURITY_SDP 0
+#define BT_SECURITY_LOW 1
+#define BT_SECURITY_MEDIUM 2
+#define BT_SECURITY_HIGH 3
+
#define BT_DEFER_SETUP 7
#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 {
__u16 link_policy;
__u32 link_mode;
__u8 auth_type;
+ __u8 sec_level;
__u8 power_save;
unsigned long pend;
@@ -325,12 +326,11 @@ int hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev);
void hci_conn_check_pending(struct hci_dev *hdev);
-struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type);
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
-int hci_conn_auth(struct hci_conn *conn);
-int hci_conn_encrypt(struct hci_conn *conn);
+int hci_conn_security(struct hci_conn *conn, __u8 sec_level);
int hci_conn_change_link_key(struct hci_conn *conn);
-int hci_conn_switch_role(struct hci_conn *conn, uint8_t role);
+int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
void hci_conn_enter_active_mode(struct hci_conn *conn);
void hci_conn_enter_sniff_mode(struct hci_conn *conn);
@@ -470,26 +470,25 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
/* ----- HCI protocols ----- */
struct hci_proto {
- char *name;
+ char *name;
unsigned int id;
unsigned long flags;
void *priv;
- int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
+ int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
int (*connect_cfm) (struct hci_conn *conn, __u8 status);
int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
- int (*auth_cfm) (struct hci_conn *conn, __u8 status);
- int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
+ int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
};
static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
{
register struct hci_proto *hp;
int mask = 0;
-
+
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->connect_ind)
mask |= hp->connect_ind(hdev, bdaddr, type);
@@ -530,14 +529,20 @@ static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
{
register struct hci_proto *hp;
+ __u8 encrypt;
+
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+ return;
+
+ encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
hp = hci_proto[HCI_PROTO_L2CAP];
- if (hp && hp->auth_cfm)
- hp->auth_cfm(conn, status);
+ if (hp && hp->security_cfm)
+ hp->security_cfm(conn, status, encrypt);
hp = hci_proto[HCI_PROTO_SCO];
- if (hp && hp->auth_cfm)
- hp->auth_cfm(conn, status);
+ if (hp && hp->security_cfm)
+ hp->security_cfm(conn, status, encrypt);
}
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
register struct hci_proto *hp;
hp = hci_proto[HCI_PROTO_L2CAP];
- if (hp && hp->encrypt_cfm)
- hp->encrypt_cfm(conn, status, encrypt);
+ if (hp && hp->security_cfm)
+ hp->security_cfm(conn, status, encrypt);
hp = hci_proto[HCI_PROTO_SCO];
- if (hp && hp->encrypt_cfm)
- hp->encrypt_cfm(conn, status, encrypt);
+ if (hp && hp->security_cfm)
+ hp->security_cfm(conn, status, encrypt);
}
int hci_register_proto(struct hci_proto *hproto);
@@ -562,8 +567,7 @@ struct hci_cb {
char *name;
- void (*auth_cfm) (struct hci_conn *conn, __u8 status);
- void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
+ void (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt);
void (*key_change_cfm) (struct hci_conn *conn, __u8 status);
void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role);
};
@@ -571,14 +575,20 @@ struct hci_cb {
static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
{
struct list_head *p;
+ __u8 encrypt;
hci_proto_auth_cfm(conn, status);
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+ return;
+
+ encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
- if (cb->auth_cfm)
- cb->auth_cfm(conn, status);
+ if (cb->security_cfm)
+ cb->security_cfm(conn, status, encrypt);
}
read_unlock_bh(&hci_cb_list_lock);
}
@@ -592,8 +602,8 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
read_lock_bh(&hci_cb_list_lock);
list_for_each(p, &hci_cb_list) {
struct hci_cb *cb = list_entry(p, struct hci_cb, list);
- if (cb->encrypt_cfm)
- cb->encrypt_cfm(conn, status, encrypt);
+ if (cb->security_cfm)
+ cb->security_cfm(conn, status, encrypt);
}
read_unlock_bh(&hci_cb_list_lock);
}