Commit c70a7e4c authored by Marcel Holtmann's avatar Marcel Holtmann
Browse files

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -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;
};
};
+32 −8
Original line number Original line Diff line number Diff line
@@ -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,


			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,
{
{
	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,
		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,
		 */
		 */
		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,
		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,
		 */
		 */
		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,
		 */
		 */
		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,
	 * 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);
}
}