aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-07-09 05:59:17 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-07-09 06:25:27 -0400
commit70c464256310e1c3716099b9d02ece4169272f73 (patch)
tree8254be9723dbb069038996ca387995739d64da7f /net
parentdee58c1ed5e29eb57fa9358a8ff27848b72f3b7d (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.c112
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
2124static 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
2124static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 2133static 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