aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2011-05-26 15:23:50 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-08 15:58:17 -0400
commit76c8686f8871f1bcb2dc8b4c5311cd0e2f73d4cd (patch)
tree379c715844e57ebb14abbf0285c3f4afa414716a
parent57a56fd41b1264d639175726414ae7e510ec683b (diff)
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: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/hci_core.h13
-rw-r--r--net/bluetooth/hci_core.c64
2 files changed, 77 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6c994c004d15..10dfb85ad6a1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -89,6 +89,12 @@ struct oob_data {
89 u8 randomizer[16]; 89 u8 randomizer[16];
90}; 90};
91 91
92struct adv_entry {
93 struct list_head list;
94 bdaddr_t bdaddr;
95 u8 bdaddr_type;
96};
97
92#define NUM_REASSEMBLY 4 98#define NUM_REASSEMBLY 4
93struct hci_dev { 99struct hci_dev {
94 struct list_head list; 100 struct list_head list;
@@ -181,6 +187,8 @@ struct hci_dev {
181 187
182 struct list_head remote_oob_data; 188 struct list_head remote_oob_data;
183 189
190 struct list_head adv_entries;
191
184 struct hci_dev_stats stat; 192 struct hci_dev_stats stat;
185 193
186 struct sk_buff_head driver_init; 194 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,
527 u8 *randomizer); 535 u8 *randomizer);
528int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); 536int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
529 537
538int hci_adv_entries_clear(struct hci_dev *hdev);
539struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
540int hci_add_adv_entry(struct hci_dev *hdev,
541 struct hci_ev_le_advertising_info *ev);
542
530void hci_del_off_timer(struct hci_dev *hdev); 543void hci_del_off_timer(struct hci_dev *hdev);
531 544
532void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 545void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 815269b07f20..cc40f221f5e7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1202,6 +1202,67 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
1202 return 0; 1202 return 0;
1203} 1203}
1204 1204
1205int hci_adv_entries_clear(struct hci_dev *hdev)
1206{
1207 struct adv_entry *entry, *tmp;
1208
1209 list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
1210 list_del(&entry->list);
1211 kfree(entry);
1212 }
1213
1214 BT_DBG("%s adv cache cleared", hdev->name);
1215
1216 return 0;
1217}
1218
1219struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
1220{
1221 struct adv_entry *entry;
1222
1223 list_for_each_entry(entry, &hdev->adv_entries, list)
1224 if (bacmp(bdaddr, &entry->bdaddr) == 0)
1225 return entry;
1226
1227 return NULL;
1228}
1229
1230static inline int is_connectable_adv(u8 evt_type)
1231{
1232 if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
1233 return 1;
1234
1235 return 0;
1236}
1237
1238int hci_add_adv_entry(struct hci_dev *hdev,
1239 struct hci_ev_le_advertising_info *ev)
1240{
1241 struct adv_entry *entry;
1242
1243 if (!is_connectable_adv(ev->evt_type))
1244 return -EINVAL;
1245
1246 /* Only new entries should be added to adv_entries. So, if
1247 * bdaddr was found, don't add it. */
1248 if (hci_find_adv_entry(hdev, &ev->bdaddr))
1249 return 0;
1250
1251 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
1252 if (!entry)
1253 return -ENOMEM;
1254
1255 bacpy(&entry->bdaddr, &ev->bdaddr);
1256 entry->bdaddr_type = ev->bdaddr_type;
1257
1258 list_add(&entry->list, &hdev->adv_entries);
1259
1260 BT_DBG("%s adv entry added: address %s type %u", hdev->name,
1261 batostr(&entry->bdaddr), entry->bdaddr_type);
1262
1263 return 0;
1264}
1265
1205/* Register HCI device */ 1266/* Register HCI device */
1206int hci_register_dev(struct hci_dev *hdev) 1267int hci_register_dev(struct hci_dev *hdev)
1207{ 1268{
@@ -1268,6 +1329,8 @@ int hci_register_dev(struct hci_dev *hdev)
1268 1329
1269 INIT_LIST_HEAD(&hdev->remote_oob_data); 1330 INIT_LIST_HEAD(&hdev->remote_oob_data);
1270 1331
1332 INIT_LIST_HEAD(&hdev->adv_entries);
1333
1271 INIT_WORK(&hdev->power_on, hci_power_on); 1334 INIT_WORK(&hdev->power_on, hci_power_on);
1272 INIT_WORK(&hdev->power_off, hci_power_off); 1335 INIT_WORK(&hdev->power_off, hci_power_off);
1273 setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); 1336 setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1348,6 +1411,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
1348 hci_uuids_clear(hdev); 1411 hci_uuids_clear(hdev);
1349 hci_link_keys_clear(hdev); 1412 hci_link_keys_clear(hdev);
1350 hci_remote_oob_data_clear(hdev); 1413 hci_remote_oob_data_clear(hdev);
1414 hci_adv_entries_clear(hdev);
1351 hci_dev_unlock_bh(hdev); 1415 hci_dev_unlock_bh(hdev);
1352 1416
1353 __hci_dev_put(hdev); 1417 __hci_dev_put(hdev);