From 6d2c34e30186311ecd33dd7786e179cf5a861279 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 4 Jan 2011 15:40:05 +0200 Subject: [PATCH] --- yaml --- r: 237315 b: refs/heads/master c: 03b555e119de8288a16e086e1fbd223d9b429d3d h: refs/heads/master i: 237313: 9c8d84a89cd19252da075aab8ed4dc8e6a4743fc 237311: c9406ba6e633fd52e22f0f9334a3690f29d5e024 v: v3 --- [refs] | 2 +- trunk/include/net/bluetooth/hci.h | 14 +++++++ trunk/include/net/bluetooth/hci_core.h | 4 ++ trunk/net/bluetooth/hci_event.c | 55 +++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 6f7ae082421c..129065efe155 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 930e13363fb0e94db6e8b59c54dfb5c59355113e +refs/heads/master: 03b555e119de8288a16e086e1fbd223d9b429d3d diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index f0c25b5ba4b2..65cab137e19f 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -384,6 +384,12 @@ struct hci_cp_reject_sync_conn_req { __u8 reason; } __packed; +#define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 +struct hci_cp_io_capability_neg_reply { + bdaddr_t bdaddr; + __u8 reason; +} __packed; + #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { __le16 handle; @@ -840,6 +846,14 @@ struct hci_ev_io_capa_request { bdaddr_t bdaddr; } __packed; +#define HCI_EV_IO_CAPA_REPLY 0x32 +struct hci_ev_io_capa_reply { + bdaddr_t bdaddr; + __u8 capability; + __u8 oob_data; + __u8 authentication; +} __packed; + #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 struct hci_ev_simple_pair_complete { __u8 status; diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index 8ee0b8bac77c..dc8084a139ed 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -201,6 +201,10 @@ struct hci_conn { __u16 disc_timeout; unsigned long pend; + __u8 remote_cap; + __u8 remote_oob; + __u8 remote_auth; + unsigned int sent; struct sk_buff_head data_q; diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index a8a38f17ef78..cf3014ae00e4 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -1595,6 +1595,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff hci_conn_put(conn); } + if (!test_bit(HCI_PAIRABLE, &hdev->flags)) + hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, + sizeof(ev->bdaddr), &ev->bdaddr); + hci_dev_unlock(hdev); } @@ -1885,9 +1889,52 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); - if (conn) - hci_conn_hold(conn); + if (!conn) + goto unlock; + + hci_conn_hold(conn); + + if (!test_bit(HCI_MGMT, &hdev->flags)) + goto unlock; + + if (test_bit(HCI_PAIRABLE, &hdev->flags) || + (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { + /* FIXME: Do IO capa response based on information + * provided through the management interface */ + } else { + struct hci_cp_io_capability_neg_reply cp; + + bacpy(&cp.bdaddr, &ev->bdaddr); + cp.reason = 0x16; /* Pairing not allowed */ + hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, + sizeof(cp), &cp); + } + +unlock: + hci_dev_unlock(hdev); +} + +static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct hci_ev_io_capa_reply *ev = (void *) skb->data; + struct hci_conn *conn; + + BT_DBG("%s", hdev->name); + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); + if (!conn) + goto unlock; + + hci_conn_hold(conn); + + conn->remote_cap = ev->capability; + conn->remote_oob = ev->oob_data; + conn->remote_auth = ev->authentication; + +unlock: hci_dev_unlock(hdev); } @@ -2051,6 +2098,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_io_capa_request_evt(hdev, skb); break; + case HCI_EV_IO_CAPA_REPLY: + hci_io_capa_reply_evt(hdev, skb); + break; + case HCI_EV_SIMPLE_PAIR_COMPLETE: hci_simple_pair_complete_evt(hdev, skb); break;