Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76c8686f authored by Andre Guedes's avatar Andre Guedes Committed by Gustavo Padovan
Browse files

Bluetooth: LE advertising cache



This patch implements the LE advertising cache. It stores sensitive
information (bdaddr and bdaddr_type so far) gathered from LE
advertising report events.

Only advertising entries from connectables devices are added to the
cache.

Signed-off-by: default avatarAndre Guedes <andre.guedes@openbossa.org>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 57a56fd4
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,12 @@ struct oob_data {
	u8 randomizer[16];
	u8 randomizer[16];
};
};


struct adv_entry {
	struct list_head list;
	bdaddr_t bdaddr;
	u8 bdaddr_type;
};

#define NUM_REASSEMBLY 4
#define NUM_REASSEMBLY 4
struct hci_dev {
struct hci_dev {
	struct list_head list;
	struct list_head list;
@@ -181,6 +187,8 @@ struct hci_dev {


	struct list_head	remote_oob_data;
	struct list_head	remote_oob_data;


	struct list_head	adv_entries;

	struct hci_dev_stats	stat;
	struct hci_dev_stats	stat;


	struct sk_buff_head	driver_init;
	struct sk_buff_head	driver_init;
@@ -527,6 +535,11 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
								u8 *randomizer);
								u8 *randomizer);
int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);


int hci_adv_entries_clear(struct hci_dev *hdev);
struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_adv_entry(struct hci_dev *hdev,
					struct hci_ev_le_advertising_info *ev);

void hci_del_off_timer(struct hci_dev *hdev);
void hci_del_off_timer(struct hci_dev *hdev);


void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
+64 −0
Original line number Original line Diff line number Diff line
@@ -1202,6 +1202,67 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
	return 0;
	return 0;
}
}


int hci_adv_entries_clear(struct hci_dev *hdev)
{
	struct adv_entry *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
		list_del(&entry->list);
		kfree(entry);
	}

	BT_DBG("%s adv cache cleared", hdev->name);

	return 0;
}

struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
	struct adv_entry *entry;

	list_for_each_entry(entry, &hdev->adv_entries, list)
		if (bacmp(bdaddr, &entry->bdaddr) == 0)
			return entry;

	return NULL;
}

static inline int is_connectable_adv(u8 evt_type)
{
	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
		return 1;

	return 0;
}

int hci_add_adv_entry(struct hci_dev *hdev,
					struct hci_ev_le_advertising_info *ev)
{
	struct adv_entry *entry;

	if (!is_connectable_adv(ev->evt_type))
		return -EINVAL;

	/* Only new entries should be added to adv_entries. So, if
	 * bdaddr was found, don't add it. */
	if (hci_find_adv_entry(hdev, &ev->bdaddr))
		return 0;

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;

	bacpy(&entry->bdaddr, &ev->bdaddr);
	entry->bdaddr_type = ev->bdaddr_type;

	list_add(&entry->list, &hdev->adv_entries);

	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
				batostr(&entry->bdaddr), entry->bdaddr_type);

	return 0;
}

/* Register HCI device */
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
int hci_register_dev(struct hci_dev *hdev)
{
{
@@ -1268,6 +1329,8 @@ int hci_register_dev(struct hci_dev *hdev)


	INIT_LIST_HEAD(&hdev->remote_oob_data);
	INIT_LIST_HEAD(&hdev->remote_oob_data);


	INIT_LIST_HEAD(&hdev->adv_entries);

	INIT_WORK(&hdev->power_on, hci_power_on);
	INIT_WORK(&hdev->power_on, hci_power_on);
	INIT_WORK(&hdev->power_off, hci_power_off);
	INIT_WORK(&hdev->power_off, hci_power_off);
	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1348,6 +1411,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
	hci_uuids_clear(hdev);
	hci_uuids_clear(hdev);
	hci_link_keys_clear(hdev);
	hci_link_keys_clear(hdev);
	hci_remote_oob_data_clear(hdev);
	hci_remote_oob_data_clear(hdev);
	hci_adv_entries_clear(hdev);
	hci_dev_unlock_bh(hdev);
	hci_dev_unlock_bh(hdev);


	__hci_dev_put(hdev);
	__hci_dev_put(hdev);