aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/bluetooth
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-05-08 18:29:27 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-05-08 18:29:27 -0700
commitd585a021c0b10b0477d6b608c53e1feb8cde0507 (patch)
tree5ca059da1db7f15d4b29427644ad9c08270c885c /include/net/bluetooth
parent84e5b0d00f8f84c4ae226be131d4bebbcee88bd3 (diff)
parent091bf7624d1c90cec9e578a18529f615213ff847 (diff)
downloadkernel_samsung_smdk4412-d585a021c0b10b0477d6b608c53e1feb8cde0507.tar.gz
kernel_samsung_smdk4412-d585a021c0b10b0477d6b608c53e1feb8cde0507.tar.bz2
kernel_samsung_smdk4412-d585a021c0b10b0477d6b608c53e1feb8cde0507.zip
Merge commit 'v2.6.30-rc5' into next
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r--include/net/bluetooth/bluetooth.h12
-rw-r--r--include/net/bluetooth/hci.h9
-rw-r--r--include/net/bluetooth/hci_core.h93
-rw-r--r--include/net/bluetooth/l2cap.h13
-rw-r--r--include/net/bluetooth/rfcomm.h20
5 files changed, 106 insertions, 41 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index a04f8463ac7..3ad5390a4dd 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -53,6 +53,17 @@
#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)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
@@ -108,6 +119,7 @@ struct bt_sock {
bdaddr_t dst;
struct list_head accept_q;
struct sock *parent;
+ u32 defer_setup;
};
struct bt_sock_list {
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3645139e68c..ed3aea1605e 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -101,6 +101,7 @@ enum {
/* HCI timeouts */
#define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */
#define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */
+#define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */
#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */
#define HCI_INIT_TIMEOUT (10000) /* 10 seconds */
@@ -133,8 +134,13 @@ enum {
#define ESCO_EV3 0x0008
#define ESCO_EV4 0x0010
#define ESCO_EV5 0x0020
+#define ESCO_2EV3 0x0040
+#define ESCO_3EV3 0x0080
+#define ESCO_2EV5 0x0100
+#define ESCO_3EV5 0x0200
#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
+#define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
/* ACL flags */
#define ACL_CONT 0x01
@@ -176,6 +182,9 @@ enum {
#define LMP_EV5 0x02
#define LMP_SNIFF_SUBR 0x02
+#define LMP_EDR_ESCO_2M 0x20
+#define LMP_EDR_ESCO_3M 0x40
+#define LMP_EDR_3S_ESCO 0x80
#define LMP_SIMPLE_PAIR 0x08
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 46a43b721dd..73aead222b3 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,7 +169,9 @@ struct hci_conn {
__u16 link_policy;
__u32 link_mode;
__u8 auth_type;
+ __u8 sec_level;
__u8 power_save;
+ __u16 disc_timeout;
unsigned long pend;
unsigned int sent;
@@ -179,7 +181,8 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
- struct work_struct work;
+ struct work_struct work_add;
+ struct work_struct work_del;
struct device dev;
@@ -325,12 +328,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, __u8 auth_type);
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);
@@ -348,9 +350,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
if (conn->type == ACL_LINK) {
del_timer(&conn->idle_timer);
if (conn->state == BT_CONNECTED) {
- timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
+ timeo = msecs_to_jiffies(conn->disc_timeout);
if (!conn->out)
- timeo *= 5;
+ timeo *= 2;
} else
timeo = msecs_to_jiffies(10);
} else
@@ -455,6 +457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
+void hci_conn_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn);
@@ -470,26 +473,26 @@ 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 (*disconn_ind) (struct hci_conn *conn);
+ int (*disconn_cfm) (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);
@@ -514,30 +517,52 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
hp->connect_cfm(conn, status);
}
-static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
+static inline int hci_proto_disconn_ind(struct hci_conn *conn)
{
register struct hci_proto *hp;
+ int reason = 0x13;
hp = hci_proto[HCI_PROTO_L2CAP];
if (hp && hp->disconn_ind)
- hp->disconn_ind(conn, reason);
+ reason = hp->disconn_ind(conn);
hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->disconn_ind)
- hp->disconn_ind(conn, reason);
+ reason = hp->disconn_ind(conn);
+
+ return reason;
+}
+
+static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
+{
+ register struct hci_proto *hp;
+
+ hp = hci_proto[HCI_PROTO_L2CAP];
+ if (hp && hp->disconn_cfm)
+ hp->disconn_cfm(conn, reason);
+
+ hp = hci_proto[HCI_PROTO_SCO];
+ if (hp && hp->disconn_cfm)
+ hp->disconn_cfm(conn, 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 +570,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 +587,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 +595,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);
}
@@ -587,13 +617,16 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
{
struct list_head *p;
+ if (conn->sec_level == BT_SECURITY_SDP)
+ conn->sec_level = BT_SECURITY_LOW;
+
hci_proto_encrypt_cfm(conn, status, encrypt);
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);
}
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 73e115bc12d..f566aa1f0a4 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -37,6 +37,7 @@ struct sockaddr_l2 {
sa_family_t l2_family;
__le16 l2_psm;
bdaddr_t l2_bdaddr;
+ __le16 l2_cid;
};
/* L2CAP socket options */
@@ -185,6 +186,7 @@ struct l2cap_info_rsp {
/* info type */
#define L2CAP_IT_CL_MTU 0x0001
#define L2CAP_IT_FEAT_MASK 0x0002
+#define L2CAP_IT_FIXED_CHAN 0x0003
/* info result */
#define L2CAP_IR_SUCCESS 0x0000
@@ -219,11 +221,14 @@ struct l2cap_conn {
__u8 rx_ident;
__u8 tx_ident;
+ __u8 disc_reason;
+
struct l2cap_chan_list chan_list;
};
#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
-#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x02
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
+#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
/* ----- L2CAP channel and socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
@@ -237,8 +242,9 @@ struct l2cap_pinfo {
__u16 imtu;
__u16 omtu;
__u16 flush_to;
-
- __u32 link_mode;
+ __u8 sec_level;
+ __u8 role_switch;
+ __u8 force_reliable;
__u8 conf_req[64];
__u8 conf_len;
@@ -257,6 +263,7 @@ struct l2cap_pinfo {
#define L2CAP_CONF_REQ_SENT 0x01
#define L2CAP_CONF_INPUT_DONE 0x02
#define L2CAP_CONF_OUTPUT_DONE 0x04
+#define L2CAP_CONF_CONNECT_PEND 0x80
#define L2CAP_CONF_MAX_RETRIES 2
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 4dc8d92a463..80072611d26 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -183,8 +183,9 @@ struct rfcomm_dlc {
u8 remote_v24_sig;
u8 mscex;
u8 out;
-
- u32 link_mode;
+ u8 sec_level;
+ u8 role_switch;
+ u32 defer_setup;
uint mtu;
uint cfc;
@@ -202,10 +203,12 @@ struct rfcomm_dlc {
#define RFCOMM_RX_THROTTLED 0
#define RFCOMM_TX_THROTTLED 1
#define RFCOMM_TIMED_OUT 2
-#define RFCOMM_MSC_PENDING 3
-#define RFCOMM_AUTH_PENDING 4
-#define RFCOMM_AUTH_ACCEPT 5
-#define RFCOMM_AUTH_REJECT 6
+#define RFCOMM_MSC_PENDING 3
+#define RFCOMM_SEC_PENDING 4
+#define RFCOMM_AUTH_PENDING 5
+#define RFCOMM_AUTH_ACCEPT 6
+#define RFCOMM_AUTH_REJECT 7
+#define RFCOMM_DEFER_SETUP 8
/* Scheduling flags and events */
#define RFCOMM_SCHED_STATE 0
@@ -239,6 +242,7 @@ int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
+void rfcomm_dlc_accept(struct rfcomm_dlc *d);
#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
@@ -304,7 +308,8 @@ struct rfcomm_pinfo {
struct bt_sock bt;
struct rfcomm_dlc *dlc;
u8 channel;
- u32 link_mode;
+ u8 sec_level;
+ u8 role_switch;
};
int rfcomm_init_sockets(void);
@@ -333,7 +338,6 @@ struct rfcomm_dev_req {
bdaddr_t src;
bdaddr_t dst;
u8 channel;
-
};
struct rfcomm_dev_info {