Commit c70a7e4c authored by Marcel Holtmann's avatar Marcel Holtmann

Bluetooth: Add support for Not Connectable flag for Device Found events

The Device Found events of the management interface should indicate if
it is possible to connect to a remote device or if it is broadcaster
only advertising. To allow this differentation the Not Connectable flag
is introduced that will be set when it is known that a device can not
be connected.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent af58925c
...@@ -71,6 +71,7 @@ struct discovery_state { ...@@ -71,6 +71,7 @@ struct discovery_state {
bdaddr_t last_adv_addr; bdaddr_t last_adv_addr;
u8 last_adv_addr_type; u8 last_adv_addr_type;
s8 last_adv_rssi; s8 last_adv_rssi;
u32 last_adv_flags;
u8 last_adv_data[HCI_MAX_AD_LENGTH]; u8 last_adv_data[HCI_MAX_AD_LENGTH];
u8 last_adv_data_len; u8 last_adv_data_len;
}; };
......
...@@ -1089,13 +1089,15 @@ static void clear_pending_adv_report(struct hci_dev *hdev) ...@@ -1089,13 +1089,15 @@ static void clear_pending_adv_report(struct hci_dev *hdev)
} }
static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr, static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 bdaddr_type, s8 rssi, u8 *data, u8 len) u8 bdaddr_type, s8 rssi, u32 flags,
u8 *data, u8 len)
{ {
struct discovery_state *d = &hdev->discovery; struct discovery_state *d = &hdev->discovery;
bacpy(&d->last_adv_addr, bdaddr); bacpy(&d->last_adv_addr, bdaddr);
d->last_adv_addr_type = bdaddr_type; d->last_adv_addr_type = bdaddr_type;
d->last_adv_rssi = rssi; d->last_adv_rssi = rssi;
d->last_adv_flags = flags;
memcpy(d->last_adv_data, data, len); memcpy(d->last_adv_data, data, len);
d->last_adv_data_len = len; d->last_adv_data_len = len;
} }
...@@ -1132,7 +1134,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, ...@@ -1132,7 +1134,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL, d->last_adv_addr_type, NULL,
d->last_adv_rssi, 0, d->last_adv_rssi, d->last_adv_flags,
d->last_adv_data, d->last_adv_data,
d->last_adv_data_len, NULL, 0); d->last_adv_data_len, NULL, 0);
} }
...@@ -4209,6 +4211,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4209,6 +4211,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
{ {
struct discovery_state *d = &hdev->discovery; struct discovery_state *d = &hdev->discovery;
bool match; bool match;
u32 flags;
/* Passive scanning shouldn't trigger any device found events */ /* Passive scanning shouldn't trigger any device found events */
if (hdev->le_scan_type == LE_SCAN_PASSIVE) { if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
...@@ -4217,6 +4220,27 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4217,6 +4220,27 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
return; return;
} }
/* When receiving non-connectable or scannable undirected
* advertising reports, this means that the remote device is
* not connectable and then clearly indicate this in the
* device found event.
*
* When receiving a scan response, then there is no way to
* know if the remote device is connectable or not. However
* since scan responses are merged with a previously seen
* advertising report, the flags field from that report
* will be used.
*
* In the really unlikely case that a controller get confused
* and just sends a scan response event, then it is marked as
* not connectable as well.
*/
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
type == LE_ADV_SCAN_RSP)
flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
else
flags = 0;
/* If there's nothing pending either store the data from this /* If there's nothing pending either store the data from this
* event or send an immediate device found event if the data * event or send an immediate device found event if the data
* should not be stored for later. * should not be stored for later.
...@@ -4227,12 +4251,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4227,12 +4251,12 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/ */
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type, store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, data, len); rssi, flags, data, len);
return; return;
} }
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, 0, data, len, NULL, 0); rssi, flags, data, len, NULL, 0);
return; return;
} }
...@@ -4249,7 +4273,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4249,7 +4273,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
if (!match) if (!match)
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL, d->last_adv_addr_type, NULL,
d->last_adv_rssi, 0, d->last_adv_rssi, d->last_adv_flags,
d->last_adv_data, d->last_adv_data,
d->last_adv_data_len, NULL, 0); d->last_adv_data_len, NULL, 0);
...@@ -4258,7 +4282,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4258,7 +4282,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/ */
if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) { if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
store_pending_adv_report(hdev, bdaddr, bdaddr_type, store_pending_adv_report(hdev, bdaddr, bdaddr_type,
rssi, data, len); rssi, flags, data, len);
return; return;
} }
...@@ -4267,7 +4291,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4267,7 +4291,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
*/ */
clear_pending_adv_report(hdev); clear_pending_adv_report(hdev);
mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
rssi, 0, data, len, NULL, 0); rssi, flags, data, len, NULL, 0);
return; return;
} }
...@@ -4276,7 +4300,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, ...@@ -4276,7 +4300,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
* sending a merged device found event. * sending a merged device found event.
*/ */
mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
d->last_adv_addr_type, NULL, rssi, 0, d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
d->last_adv_data, d->last_adv_data_len, data, len); d->last_adv_data, d->last_adv_data_len, data, len);
clear_pending_adv_report(hdev); clear_pending_adv_report(hdev);
} }
......
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