Commit a1775846 authored by John W. Linville's avatar John W. Linville
parents e46395a4 b8534e0f
...@@ -415,6 +415,17 @@ struct hci_cp_io_capability_reply { ...@@ -415,6 +415,17 @@ struct hci_cp_io_capability_reply {
__u8 authentication; __u8 authentication;
} __packed; } __packed;
#define HCI_OP_USER_CONFIRM_REPLY 0x042c
struct hci_cp_user_confirm_reply {
bdaddr_t bdaddr;
} __packed;
struct hci_rp_user_confirm_reply {
__u8 status;
bdaddr_t bdaddr;
} __packed;
#define HCI_OP_USER_CONFIRM_NEG_REPLY 0x042d
#define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434
struct hci_cp_io_capability_neg_reply { struct hci_cp_io_capability_neg_reply {
bdaddr_t bdaddr; bdaddr_t bdaddr;
...@@ -936,6 +947,12 @@ struct hci_ev_io_capa_reply { ...@@ -936,6 +947,12 @@ struct hci_ev_io_capa_reply {
__u8 authentication; __u8 authentication;
} __packed; } __packed;
#define HCI_EV_USER_CONFIRM_REQUEST 0x33
struct hci_ev_user_confirm_req {
bdaddr_t bdaddr;
__le32 passkey;
} __packed;
#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct hci_ev_simple_pair_complete { struct hci_ev_simple_pair_complete {
__u8 status; __u8 status;
......
...@@ -248,6 +248,10 @@ struct hci_conn { ...@@ -248,6 +248,10 @@ struct hci_conn {
void *priv; void *priv;
struct hci_conn *link; struct hci_conn *link;
void (*connect_cfm_cb) (struct hci_conn *conn, u8 status);
void (*security_cfm_cb) (struct hci_conn *conn, u8 status);
void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason);
}; };
extern struct hci_proto *hci_proto[]; extern struct hci_proto *hci_proto[];
...@@ -571,6 +575,9 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) ...@@ -571,6 +575,9 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
hp = hci_proto[HCI_PROTO_SCO]; hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->connect_cfm) if (hp && hp->connect_cfm)
hp->connect_cfm(conn, status); hp->connect_cfm(conn, status);
if (conn->connect_cfm_cb)
conn->connect_cfm_cb(conn, status);
} }
static inline int hci_proto_disconn_ind(struct hci_conn *conn) static inline int hci_proto_disconn_ind(struct hci_conn *conn)
...@@ -600,6 +607,9 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) ...@@ -600,6 +607,9 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
hp = hci_proto[HCI_PROTO_SCO]; hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->disconn_cfm) if (hp && hp->disconn_cfm)
hp->disconn_cfm(conn, reason); hp->disconn_cfm(conn, reason);
if (conn->disconn_cfm_cb)
conn->disconn_cfm_cb(conn, reason);
} }
static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
...@@ -619,6 +629,9 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) ...@@ -619,6 +629,9 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
hp = hci_proto[HCI_PROTO_SCO]; hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->security_cfm) if (hp && hp->security_cfm)
hp->security_cfm(conn, status, encrypt); hp->security_cfm(conn, status, encrypt);
if (conn->security_cfm_cb)
conn->security_cfm_cb(conn, status);
} }
static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
...@@ -632,6 +645,9 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u ...@@ -632,6 +645,9 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u
hp = hci_proto[HCI_PROTO_SCO]; hp = hci_proto[HCI_PROTO_SCO];
if (hp && hp->security_cfm) if (hp && hp->security_cfm)
hp->security_cfm(conn, status, encrypt); hp->security_cfm(conn, status, encrypt);
if (conn->security_cfm_cb)
conn->security_cfm_cb(conn, status);
} }
int hci_register_proto(struct hci_proto *hproto); int hci_register_proto(struct hci_proto *hproto);
...@@ -746,6 +762,11 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); ...@@ -746,6 +762,11 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr); int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
/* HCI info for socket */ /* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk) #define hci_pi(sk) ((struct hci_pinfo *) sk)
......
...@@ -21,11 +21,13 @@ ...@@ -21,11 +21,13 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
#define MGMT_INDEX_NONE 0xFFFF
struct mgmt_hdr { struct mgmt_hdr {
__le16 opcode; __le16 opcode;
__le16 index;
__le16 len; __le16 len;
} __packed; } __packed;
#define MGMT_HDR_SIZE 4
#define MGMT_OP_READ_VERSION 0x0001 #define MGMT_OP_READ_VERSION 0x0001
struct mgmt_rp_read_version { struct mgmt_rp_read_version {
...@@ -40,11 +42,7 @@ struct mgmt_rp_read_index_list { ...@@ -40,11 +42,7 @@ struct mgmt_rp_read_index_list {
} __packed; } __packed;
#define MGMT_OP_READ_INFO 0x0004 #define MGMT_OP_READ_INFO 0x0004
struct mgmt_cp_read_info {
__le16 index;
} __packed;
struct mgmt_rp_read_info { struct mgmt_rp_read_info {
__le16 index;
__u8 type; __u8 type;
__u8 powered; __u8 powered;
__u8 connectable; __u8 connectable;
...@@ -60,7 +58,6 @@ struct mgmt_rp_read_info { ...@@ -60,7 +58,6 @@ struct mgmt_rp_read_info {
} __packed; } __packed;
struct mgmt_mode { struct mgmt_mode {
__le16 index;
__u8 val; __u8 val;
} __packed; } __packed;
...@@ -74,27 +71,23 @@ struct mgmt_mode { ...@@ -74,27 +71,23 @@ struct mgmt_mode {
#define MGMT_OP_ADD_UUID 0x0009 #define MGMT_OP_ADD_UUID 0x0009
struct mgmt_cp_add_uuid { struct mgmt_cp_add_uuid {
__le16 index;
__u8 uuid[16]; __u8 uuid[16];
__u8 svc_hint; __u8 svc_hint;
} __packed; } __packed;
#define MGMT_OP_REMOVE_UUID 0x000A #define MGMT_OP_REMOVE_UUID 0x000A
struct mgmt_cp_remove_uuid { struct mgmt_cp_remove_uuid {
__le16 index;
__u8 uuid[16]; __u8 uuid[16];
} __packed; } __packed;
#define MGMT_OP_SET_DEV_CLASS 0x000B #define MGMT_OP_SET_DEV_CLASS 0x000B
struct mgmt_cp_set_dev_class { struct mgmt_cp_set_dev_class {
__le16 index;
__u8 major; __u8 major;
__u8 minor; __u8 minor;
} __packed; } __packed;
#define MGMT_OP_SET_SERVICE_CACHE 0x000C #define MGMT_OP_SET_SERVICE_CACHE 0x000C
struct mgmt_cp_set_service_cache { struct mgmt_cp_set_service_cache {
__le16 index;
__u8 enable; __u8 enable;
} __packed; } __packed;
...@@ -107,7 +100,6 @@ struct mgmt_key_info { ...@@ -107,7 +100,6 @@ struct mgmt_key_info {
#define MGMT_OP_LOAD_KEYS 0x000D #define MGMT_OP_LOAD_KEYS 0x000D
struct mgmt_cp_load_keys { struct mgmt_cp_load_keys {
__le16 index;
__u8 debug_keys; __u8 debug_keys;
__le16 key_count; __le16 key_count;
struct mgmt_key_info keys[0]; struct mgmt_key_info keys[0];
...@@ -115,51 +107,66 @@ struct mgmt_cp_load_keys { ...@@ -115,51 +107,66 @@ struct mgmt_cp_load_keys {
#define MGMT_OP_REMOVE_KEY 0x000E #define MGMT_OP_REMOVE_KEY 0x000E
struct mgmt_cp_remove_key { struct mgmt_cp_remove_key {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 disconnect; __u8 disconnect;
} __packed; } __packed;
#define MGMT_OP_DISCONNECT 0x000F #define MGMT_OP_DISCONNECT 0x000F
struct mgmt_cp_disconnect { struct mgmt_cp_disconnect {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
struct mgmt_rp_disconnect { struct mgmt_rp_disconnect {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_OP_GET_CONNECTIONS 0x0010 #define MGMT_OP_GET_CONNECTIONS 0x0010
struct mgmt_cp_get_connections {
__le16 index;
} __packed;
struct mgmt_rp_get_connections { struct mgmt_rp_get_connections {
__le16 index;
__le16 conn_count; __le16 conn_count;
bdaddr_t conn[0]; bdaddr_t conn[0];
} __packed; } __packed;
#define MGMT_OP_PIN_CODE_REPLY 0x0011 #define MGMT_OP_PIN_CODE_REPLY 0x0011
struct mgmt_cp_pin_code_reply { struct mgmt_cp_pin_code_reply {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 pin_len; __u8 pin_len;
__u8 pin_code[16]; __u8 pin_code[16];
} __packed; } __packed;
struct mgmt_rp_pin_code_reply {
bdaddr_t bdaddr;
uint8_t status;
} __packed;
#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012 #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012
struct mgmt_cp_pin_code_neg_reply { struct mgmt_cp_pin_code_neg_reply {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_OP_SET_IO_CAPABILITY 0x0013 #define MGMT_OP_SET_IO_CAPABILITY 0x0013
struct mgmt_cp_set_io_capability { struct mgmt_cp_set_io_capability {
__le16 index;
__u8 io_capability; __u8 io_capability;
} __packed; } __packed;
#define MGMT_OP_PAIR_DEVICE 0x0014
struct mgmt_cp_pair_device {
bdaddr_t bdaddr;
__u8 io_cap;
} __packed;
struct mgmt_rp_pair_device {
bdaddr_t bdaddr;
__u8 status;
} __packed;
#define MGMT_OP_USER_CONFIRM_REPLY 0x0015
struct mgmt_cp_user_confirm_reply {
bdaddr_t bdaddr;
} __packed;
struct mgmt_rp_user_confirm_reply {
bdaddr_t bdaddr;
__u8 status;
} __packed;
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016
#define MGMT_EV_CMD_COMPLETE 0x0001 #define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete { struct mgmt_ev_cmd_complete {
__le16 opcode; __le16 opcode;
...@@ -174,19 +181,12 @@ struct mgmt_ev_cmd_status { ...@@ -174,19 +181,12 @@ struct mgmt_ev_cmd_status {
#define MGMT_EV_CONTROLLER_ERROR 0x0003 #define MGMT_EV_CONTROLLER_ERROR 0x0003
struct mgmt_ev_controller_error { struct mgmt_ev_controller_error {
__le16 index;
__u8 error_code; __u8 error_code;
} __packed; } __packed;
#define MGMT_EV_INDEX_ADDED 0x0004 #define MGMT_EV_INDEX_ADDED 0x0004
struct mgmt_ev_index_added {
__le16 index;
} __packed;
#define MGMT_EV_INDEX_REMOVED 0x0005 #define MGMT_EV_INDEX_REMOVED 0x0005
struct mgmt_ev_index_removed {
__le16 index;
} __packed;
#define MGMT_EV_POWERED 0x0006 #define MGMT_EV_POWERED 0x0006
...@@ -198,32 +198,39 @@ struct mgmt_ev_index_removed { ...@@ -198,32 +198,39 @@ struct mgmt_ev_index_removed {
#define MGMT_EV_NEW_KEY 0x000A #define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key { struct mgmt_ev_new_key {
__le16 index;
struct mgmt_key_info key; struct mgmt_key_info key;
__u8 old_key_type; __u8 old_key_type;
} __packed; } __packed;
#define MGMT_EV_CONNECTED 0x000B #define MGMT_EV_CONNECTED 0x000B
struct mgmt_ev_connected { struct mgmt_ev_connected {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_EV_DISCONNECTED 0x000C #define MGMT_EV_DISCONNECTED 0x000C
struct mgmt_ev_disconnected { struct mgmt_ev_disconnected {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_EV_CONNECT_FAILED 0x000D #define MGMT_EV_CONNECT_FAILED 0x000D
struct mgmt_ev_connect_failed { struct mgmt_ev_connect_failed {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 status; __u8 status;
} __packed; } __packed;
#define MGMT_EV_PIN_CODE_REQUEST 0x000E #define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request { struct mgmt_ev_pin_code_request {
__le16 index;
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
__le32 value;
} __packed;
#define MGMT_EV_AUTH_FAILED 0x0010
struct mgmt_ev_auth_failed {
bdaddr_t bdaddr;
__u8 status;
} __packed;
...@@ -550,10 +550,8 @@ static int __init bt_init(void) ...@@ -550,10 +550,8 @@ static int __init bt_init(void)
goto error; goto error;
err = l2cap_init(); err = l2cap_init();
if (err < 0) { if (err < 0)
hci_sock_cleanup();
goto sock_err; goto sock_err;
}
err = sco_init(); err = sco_init();
if (err < 0) { if (err < 0) {
......
...@@ -286,6 +286,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -286,6 +286,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
conn->state = BT_OPEN; conn->state = BT_OPEN;
conn->auth_type = HCI_AT_GENERAL_BONDING; conn->auth_type = HCI_AT_GENERAL_BONDING;
conn->io_capability = hdev->io_capability; conn->io_capability = hdev->io_capability;
conn->remote_auth = 0xff;
conn->power_save = 1; conn->power_save = 1;
conn->disc_timeout = HCI_DISCONN_TIMEOUT; conn->disc_timeout = HCI_DISCONN_TIMEOUT;
...@@ -429,10 +430,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 ...@@ -429,10 +430,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
if (type == LE_LINK) { if (type == LE_LINK) {
le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
if (le)
return ERR_PTR(-EBUSY);
le = hci_conn_add(hdev, LE_LINK, dst);
if (!le) if (!le)
le = hci_conn_add(hdev, LE_LINK, dst); return ERR_PTR(-ENOMEM);
if (!le)
return NULL;
if (le->state == BT_OPEN) if (le->state == BT_OPEN)
hci_le_connect(le); hci_le_connect(le);
......
...@@ -796,6 +796,29 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, ...@@ -796,6 +796,29 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
} }
static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
rp->status);
}
static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
BT_DBG("%s status 0x%x", hdev->name, rp->status);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
rp->status);
}
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{ {
BT_DBG("%s status 0x%x", hdev->name, status); BT_DBG("%s status 0x%x", hdev->name, status);
...@@ -1401,8 +1424,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -1401,8 +1424,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (!ev->status) { if (!ev->status) {
conn->link_mode |= HCI_LM_AUTH; conn->link_mode |= HCI_LM_AUTH;
conn->sec_level = conn->pending_sec_level; conn->sec_level = conn->pending_sec_level;
} else } else {
mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
conn->sec_level = BT_SECURITY_LOW; conn->sec_level = BT_SECURITY_LOW;
}
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
...@@ -1728,6 +1753,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk ...@@ -1728,6 +1753,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_le_read_buffer_size(hdev, skb); hci_cc_le_read_buffer_size(hdev, skb);
break; break;
case HCI_OP_USER_CONFIRM_REPLY:
hci_cc_user_confirm_reply(hdev, skb);
break;
case HCI_OP_USER_CONFIRM_NEG_REPLY:
hci_cc_user_confirm_neg_reply(hdev, skb);
break;
default: default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode); BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break; break;
...@@ -2362,6 +2395,21 @@ static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -2362,6 +2395,21 @@ static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *s
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->flags))
mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
hci_dev_unlock(hdev);
}
static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_simple_pair_complete *ev = (void *) skb->data; struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
...@@ -2372,9 +2420,20 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ ...@@ -2372,9 +2420,20 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) if (!conn)
hci_conn_put(conn); goto unlock;
/* To avoid duplicate auth_failed events to user space we check
* the HCI_CONN_AUTH_PEND flag which will be set if we
* initiated the authentication. A traditional auth_complete
* event gets always produced as initiator and is also mapped to
* the mgmt_auth_failed event */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
hci_conn_put(conn);
unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
...@@ -2580,6 +2639,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2580,6 +2639,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_io_capa_reply_evt(hdev, skb); hci_io_capa_reply_evt(hdev, skb);
break; break;
case HCI_EV_USER_CONFIRM_REQUEST:
hci_user_confirm_request_evt(hdev, skb);
break;
case HCI_EV_SIMPLE_PAIR_COMPLETE: case HCI_EV_SIMPLE_PAIR_COMPLETE:
hci_simple_pair_complete_evt(hdev, skb); hci_simple_pair_complete_evt(hdev, skb);
break; break;
......
...@@ -861,7 +861,7 @@ int __init hci_sock_init(void) ...@@ -861,7 +861,7 @@ int __init hci_sock_init(void)
return err; return err;
} }
void __exit hci_sock_cleanup(void) void hci_sock_cleanup(void)
{ {
if (bt_sock_unregister(BTPROTO_HCI) < 0) if (bt_sock_unregister(BTPROTO_HCI) < 0)
BT_ERR("HCI socket unregistration failed"); BT_ERR("HCI socket unregistration failed");
......
...@@ -852,8 +852,6 @@ int l2cap_do_connect(struct sock *sk) ...@@ -852,8 +852,6 @@ int l2cap_do_connect(struct sock *sk)
hci_dev_lock_bh(hdev); hci_dev_lock_bh(hdev);
err = -ENOMEM;
auth_type = l2cap_get_auth_type(sk); auth_type = l2cap_get_auth_type(sk);
if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA) if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA)
...@@ -863,17 +861,18 @@ int l2cap_do_connect(struct sock *sk) ...@@ -863,17 +861,18 @@ int l2cap_do_connect(struct sock *sk)
hcon = hci_connect(hdev, ACL_LINK, dst, hcon = hci_connect(hdev, ACL_LINK, dst,
l2cap_pi(sk)->sec_level, auth_type); l2cap_pi(sk)->sec_level, auth_type);
if (!hcon) if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done; goto done;
}
conn = l2cap_conn_add(hcon, 0); conn = l2cap_conn_add(hcon, 0);
if (!conn) { if (!conn) {
hci_conn_put(hcon); hci_conn_put(hcon);
err = -ENOMEM;
goto done; goto done;
} }
err = 0;
/* Update source addr of the socket */ /* Update source addr of the socket */
bacpy(src, conn->src); bacpy(src, conn->src);
...@@ -892,6 +891,8 @@ int l2cap_do_connect(struct sock *sk) ...@@ -892,6 +891,8 @@ int l2cap_do_connect(struct sock *sk)
l2cap_do_start(sk); l2cap_do_start(sk);
} }
err = 0;
done: done:
hci_dev_unlock_bh(hdev); hci_dev_unlock_bh(hdev);
hci_dev_put(hdev); hci_dev_put(hdev);
...@@ -4033,8 +4034,6 @@ int __init l2cap_init(void) ...@@ -4033,8 +4034,6 @@ int __init l2cap_init(void)
BT_ERR("Failed to create L2CAP debug file"); BT_ERR("Failed to create L2CAP debug file");
} }
BT_INFO("L2CAP socket layer initialized");
return 0; return 0;
error: error:
......
This diff is collapsed.
...@@ -190,20 +190,21 @@ static int sco_connect(struct sock *sk) ...@@ -190,20 +190,21 @@ static int sco_connect(struct sock *sk)
hci_dev_lock_bh(hdev); hci_dev_lock_bh(hdev);
err = -ENOMEM;
if (lmp_esco_capable(hdev) && !disable_esco) if (lmp_esco_capable(hdev) && !disable_esco)
type = ESCO_LINK; type = ESCO_LINK;
else else
type = SCO_LINK; type = SCO_LINK;
hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING); hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
if (!hcon) if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done; goto done;
}
conn = sco_conn_add(hcon, 0); conn = sco_conn_add(hcon, 0);
if (!conn) { if (!conn) {
hci_conn_put(hcon); hci_conn_put(hcon);
err = -ENOMEM;
goto done; goto done;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment