diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-07-09 05:59:17 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-07-09 06:25:27 -0400 |
commit | 70c464256310e1c3716099b9d02ece4169272f73 (patch) | |
tree | 8254be9723dbb069038996ca387995739d64da7f /net | |
parent | dee58c1ed5e29eb57fa9358a8ff27848b72f3b7d (diff) |
Bluetooth: Refactor connection request handling
The conditions for accepting an incoming connections are already
non-trivial and will become more so once a white list is added. This
patch breaks up the checks for when to reject the request by creating a
helper function for it.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_event.c | 112 |
1 files changed, 60 insertions, 52 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 381c631423f1..6d1d5b3e9cd4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2121,10 +2121,21 @@ unlock: | |||
2121 | hci_conn_check_pending(hdev); | 2121 | hci_conn_check_pending(hdev); |
2122 | } | 2122 | } |
2123 | 2123 | ||
2124 | static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
2125 | { | ||
2126 | struct hci_cp_reject_conn_req cp; | ||
2127 | |||
2128 | bacpy(&cp.bdaddr, bdaddr); | ||
2129 | cp.reason = HCI_ERROR_REJ_BAD_ADDR; | ||
2130 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); | ||
2131 | } | ||
2132 | |||
2124 | static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2133 | static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2125 | { | 2134 | { |
2126 | struct hci_ev_conn_request *ev = (void *) skb->data; | 2135 | struct hci_ev_conn_request *ev = (void *) skb->data; |
2127 | int mask = hdev->link_mode; | 2136 | int mask = hdev->link_mode; |
2137 | struct inquiry_entry *ie; | ||
2138 | struct hci_conn *conn; | ||
2128 | __u8 flags = 0; | 2139 | __u8 flags = 0; |
2129 | 2140 | ||
2130 | BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, | 2141 | BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, |
@@ -2133,74 +2144,71 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2133 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, | 2144 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, |
2134 | &flags); | 2145 | &flags); |
2135 | 2146 | ||
2136 | if ((mask & HCI_LM_ACCEPT) && | 2147 | if (!(mask & HCI_LM_ACCEPT)) { |
2137 | !hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, | 2148 | hci_reject_conn(hdev, &ev->bdaddr); |
2149 | return; | ||
2150 | } | ||
2151 | |||
2152 | if (!hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr, | ||
2138 | BDADDR_BREDR)) { | 2153 | BDADDR_BREDR)) { |
2139 | /* Connection accepted */ | 2154 | hci_reject_conn(hdev, &ev->bdaddr); |
2140 | struct inquiry_entry *ie; | 2155 | return; |
2141 | struct hci_conn *conn; | 2156 | } |
2142 | 2157 | ||
2143 | hci_dev_lock(hdev); | 2158 | /* Connection accepted */ |
2144 | 2159 | ||
2145 | ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); | 2160 | hci_dev_lock(hdev); |
2146 | if (ie) | ||
2147 | memcpy(ie->data.dev_class, ev->dev_class, 3); | ||
2148 | 2161 | ||
2149 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, | 2162 | ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); |
2150 | &ev->bdaddr); | 2163 | if (ie) |
2164 | memcpy(ie->data.dev_class, ev->dev_class, 3); | ||
2165 | |||
2166 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, | ||
2167 | &ev->bdaddr); | ||
2168 | if (!conn) { | ||
2169 | conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); | ||
2151 | if (!conn) { | 2170 | if (!conn) { |
2152 | conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); | 2171 | BT_ERR("No memory for new connection"); |
2153 | if (!conn) { | 2172 | hci_dev_unlock(hdev); |
2154 | BT_ERR("No memory for new connection"); | 2173 | return; |
2155 | hci_dev_unlock(hdev); | ||
2156 | return; | ||
2157 | } | ||
2158 | } | 2174 | } |
2175 | } | ||
2159 | 2176 | ||
2160 | memcpy(conn->dev_class, ev->dev_class, 3); | 2177 | memcpy(conn->dev_class, ev->dev_class, 3); |
2161 | 2178 | ||
2162 | hci_dev_unlock(hdev); | 2179 | hci_dev_unlock(hdev); |
2163 | 2180 | ||
2164 | if (ev->link_type == ACL_LINK || | 2181 | if (ev->link_type == ACL_LINK || |
2165 | (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { | 2182 | (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { |
2166 | struct hci_cp_accept_conn_req cp; | 2183 | struct hci_cp_accept_conn_req cp; |
2167 | conn->state = BT_CONNECT; | 2184 | conn->state = BT_CONNECT; |
2168 | 2185 | ||
2169 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2186 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2170 | 2187 | ||
2171 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | 2188 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) |
2172 | cp.role = 0x00; /* Become master */ | 2189 | cp.role = 0x00; /* Become master */ |
2173 | else | 2190 | else |
2174 | cp.role = 0x01; /* Remain slave */ | 2191 | cp.role = 0x01; /* Remain slave */ |
2175 | 2192 | ||
2176 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), | 2193 | hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); |
2177 | &cp); | 2194 | } else if (!(flags & HCI_PROTO_DEFER)) { |
2178 | } else if (!(flags & HCI_PROTO_DEFER)) { | 2195 | struct hci_cp_accept_sync_conn_req cp; |
2179 | struct hci_cp_accept_sync_conn_req cp; | 2196 | conn->state = BT_CONNECT; |
2180 | conn->state = BT_CONNECT; | ||
2181 | 2197 | ||
2182 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2198 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2183 | cp.pkt_type = cpu_to_le16(conn->pkt_type); | 2199 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
2184 | 2200 | ||
2185 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); | 2201 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); |
2186 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); | 2202 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); |
2187 | cp.max_latency = cpu_to_le16(0xffff); | 2203 | cp.max_latency = cpu_to_le16(0xffff); |
2188 | cp.content_format = cpu_to_le16(hdev->voice_setting); | 2204 | cp.content_format = cpu_to_le16(hdev->voice_setting); |
2189 | cp.retrans_effort = 0xff; | 2205 | cp.retrans_effort = 0xff; |
2190 | 2206 | ||
2191 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, | 2207 | hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), |
2192 | sizeof(cp), &cp); | 2208 | &cp); |
2193 | } else { | ||
2194 | conn->state = BT_CONNECT2; | ||
2195 | hci_proto_connect_cfm(conn, 0); | ||
2196 | } | ||
2197 | } else { | 2209 | } else { |
2198 | /* Connection rejected */ | 2210 | conn->state = BT_CONNECT2; |
2199 | struct hci_cp_reject_conn_req cp; | 2211 | hci_proto_connect_cfm(conn, 0); |
2200 | |||
2201 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
2202 | cp.reason = HCI_ERROR_REJ_BAD_ADDR; | ||
2203 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); | ||
2204 | } | 2212 | } |
2205 | } | 2213 | } |
2206 | 2214 | ||