summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAlfonso Acosta <fons@spotify.com>2014-10-07 04:44:11 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-10-25 01:56:24 -0400
commitfd45ada9105635a69cbaa2d142d502d402eef6fe (patch)
treef4b6d3ca91123813a9163f3764c244fe64d4b8c5 /net/bluetooth
parent48ec92fa4f16c0f71e95c31490c03b6c9e0e793b (diff)
Bluetooth: Include ADV_IND report in Device Connected event
There are scenarios when autoconnecting to a device after the reception of an ADV_IND report (action 0x02), in which userland might want to examine the report's contents. For instance, the Service Data might have changed and it would be useful to know ahead of time before starting any GATT procedures. Also, the ADV_IND may contain Manufacturer Specific data which would be lost if not propagated to userland. In fact, this patch results from the need to rebond with a device lacking persistent storage which notifies about losing its LTK in ADV_IND reports. This patch appends the ADV_IND report which triggered the autoconnection to the EIR Data in the Device Connected event. Signed-off-by: Alfonso Acosta <fons@spotify.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_event.c32
-rw-r--r--net/bluetooth/mgmt.c24
2 files changed, 40 insertions, 16 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6ee7de26cbb6..96291530606d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4263,25 +4263,26 @@ static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
4263} 4263}
4264 4264
4265/* This function requires the caller holds hdev->lock */ 4265/* This function requires the caller holds hdev->lock */
4266static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, 4266static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
4267 u8 addr_type, u8 adv_type) 4267 bdaddr_t *addr,
4268 u8 addr_type, u8 adv_type)
4268{ 4269{
4269 struct hci_conn *conn; 4270 struct hci_conn *conn;
4270 struct hci_conn_params *params; 4271 struct hci_conn_params *params;
4271 4272
4272 /* If the event is not connectable don't proceed further */ 4273 /* If the event is not connectable don't proceed further */
4273 if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) 4274 if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
4274 return; 4275 return NULL;
4275 4276
4276 /* Ignore if the device is blocked */ 4277 /* Ignore if the device is blocked */
4277 if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type)) 4278 if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
4278 return; 4279 return NULL;
4279 4280
4280 /* Most controller will fail if we try to create new connections 4281 /* Most controller will fail if we try to create new connections
4281 * while we have an existing one in slave role. 4282 * while we have an existing one in slave role.
4282 */ 4283 */
4283 if (hdev->conn_hash.le_num_slave > 0) 4284 if (hdev->conn_hash.le_num_slave > 0)
4284 return; 4285 return NULL;
4285 4286
4286 /* If we're not connectable only connect devices that we have in 4287 /* If we're not connectable only connect devices that we have in
4287 * our pend_le_conns list. 4288 * our pend_le_conns list.
@@ -4289,7 +4290,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4289 params = hci_pend_le_action_lookup(&hdev->pend_le_conns, 4290 params = hci_pend_le_action_lookup(&hdev->pend_le_conns,
4290 addr, addr_type); 4291 addr, addr_type);
4291 if (!params) 4292 if (!params)
4292 return; 4293 return NULL;
4293 4294
4294 switch (params->auto_connect) { 4295 switch (params->auto_connect) {
4295 case HCI_AUTO_CONN_DIRECT: 4296 case HCI_AUTO_CONN_DIRECT:
@@ -4298,7 +4299,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4298 * incoming connections from slave devices. 4299 * incoming connections from slave devices.
4299 */ 4300 */
4300 if (adv_type != LE_ADV_DIRECT_IND) 4301 if (adv_type != LE_ADV_DIRECT_IND)
4301 return; 4302 return NULL;
4302 break; 4303 break;
4303 case HCI_AUTO_CONN_ALWAYS: 4304 case HCI_AUTO_CONN_ALWAYS:
4304 /* Devices advertising with ADV_IND or ADV_DIRECT_IND 4305 /* Devices advertising with ADV_IND or ADV_DIRECT_IND
@@ -4309,7 +4310,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4309 */ 4310 */
4310 break; 4311 break;
4311 default: 4312 default:
4312 return; 4313 return NULL;
4313 } 4314 }
4314 4315
4315 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, 4316 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
@@ -4322,7 +4323,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4322 * count consistent once the connection is established. 4323 * count consistent once the connection is established.
4323 */ 4324 */
4324 params->conn = hci_conn_get(conn); 4325 params->conn = hci_conn_get(conn);
4325 return; 4326 return conn;
4326 } 4327 }
4327 4328
4328 switch (PTR_ERR(conn)) { 4329 switch (PTR_ERR(conn)) {
@@ -4335,7 +4336,10 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4335 break; 4336 break;
4336 default: 4337 default:
4337 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn)); 4338 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4339 return NULL;
4338 } 4340 }
4341
4342 return NULL;
4339} 4343}
4340 4344
4341static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 4345static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
@@ -4343,6 +4347,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4343{ 4347{
4344 struct discovery_state *d = &hdev->discovery; 4348 struct discovery_state *d = &hdev->discovery;
4345 struct smp_irk *irk; 4349 struct smp_irk *irk;
4350 struct hci_conn *conn;
4346 bool match; 4351 bool match;
4347 u32 flags; 4352 u32 flags;
4348 4353
@@ -4354,7 +4359,14 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4354 } 4359 }
4355 4360
4356 /* Check if we have been requested to connect to this device */ 4361 /* Check if we have been requested to connect to this device */
4357 check_pending_le_conn(hdev, bdaddr, bdaddr_type, type); 4362 conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type);
4363 if (conn && type == LE_ADV_IND) {
4364 /* Store report for later inclusion by
4365 * mgmt_device_connected
4366 */
4367 memcpy(conn->le_adv_data, data, len);
4368 conn->le_adv_data_len = len;
4369 }
4358 4370
4359 /* Passive scanning shouldn't trigger any device found events, 4371 /* Passive scanning shouldn't trigger any device found events,
4360 * except for devices marked as CONN_REPORT for which we do send 4372 * except for devices marked as CONN_REPORT for which we do send
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index fc275dca94f8..10caab587cca 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6183,13 +6183,25 @@ void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
6183 6183
6184 ev->flags = __cpu_to_le32(flags); 6184 ev->flags = __cpu_to_le32(flags);
6185 6185
6186 if (name_len > 0) 6186 /* We must ensure that the EIR Data fields are ordered and
6187 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, 6187 * unique. Keep it simple for now and avoid the problem by not
6188 name, name_len); 6188 * adding any BR/EDR data to the LE adv.
6189 */
6190 if (conn->le_adv_data_len > 0) {
6191 memcpy(&ev->eir[eir_len],
6192 conn->le_adv_data, conn->le_adv_data_len);
6193 eir_len = conn->le_adv_data_len;
6194 } else {
6195 if (name_len > 0)
6196 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
6197 name, name_len);
6189 6198
6190 if (conn->dev_class && memcmp(conn->dev_class, "\0\0\0", 3) != 0) 6199 if (conn->dev_class &&
6191 eir_len = eir_append_data(ev->eir, eir_len, 6200 memcmp(conn->dev_class, "\0\0\0", 3) != 0)
6192 EIR_CLASS_OF_DEV, conn->dev_class, 3); 6201 eir_len = eir_append_data(ev->eir, eir_len,
6202 EIR_CLASS_OF_DEV,
6203 conn->dev_class, 3);
6204 }
6193 6205
6194 ev->eir_len = cpu_to_le16(eir_len); 6206 ev->eir_len = cpu_to_le16(eir_len);
6195 6207