summaryrefslogtreecommitdiff
path: root/emulator/le.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-12-14 17:03:13 +0100
committerMarcel Holtmann <marcel@holtmann.org>2014-12-14 17:03:13 +0100
commit06159d7ab3202104b6345dac7f94ed714d74fcbc (patch)
treebbe4860f10c406178cbe83e71ead9f2fbcd32b3c /emulator/le.c
parent4b2318b60dd35198919dc601cb79253026b54586 (diff)
downloadbluez-06159d7ab3202104b6345dac7f94ed714d74fcbc.tar.gz
emulator: Add support for duplicate filtering during scanning
Diffstat (limited to 'emulator/le.c')
-rw-r--r--emulator/le.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/emulator/le.c b/emulator/le.c
index ce4c5cb8c..e2330ce8e 100644
--- a/emulator/le.c
+++ b/emulator/le.c
@@ -47,6 +47,7 @@
#define WHITE_LIST_SIZE 16
#define RESOLV_LIST_SIZE 16
+#define SCAN_CACHE_SIZE 64
#define DEFAULT_TX_LEN 0x001b
#define DEFAULT_TX_TIME 0x0148
@@ -55,6 +56,11 @@
#define MAX_RX_LEN 0x00fb
#define MAX_RX_TIME 0x0848
+struct bt_peer {
+ uint8_t addr_type;
+ uint8_t addr[6];
+};
+
struct bt_le {
volatile int ref_count;
int vhci_fd;
@@ -106,6 +112,9 @@ struct bt_le {
uint8_t le_resolv_list_size;
uint8_t le_resolv_enable;
uint16_t le_resolv_timeout;
+
+ struct bt_peer scan_cache[SCAN_CACHE_SIZE];
+ uint8_t scan_cache_count;
};
static void reset_defaults(struct bt_le *hci)
@@ -271,6 +280,33 @@ static void reset_defaults(struct bt_le *hci)
hci->le_resolv_timeout = 0x0384; /* 900 secs or 15 minutes */
}
+static void clear_scan_cache(struct bt_le *hci)
+{
+ memset(hci->scan_cache, 0, sizeof(hci->scan_cache));
+ hci->scan_cache_count = 0;
+}
+
+static bool add_to_scan_cache(struct bt_le *hci, uint8_t addr_type,
+ const uint8_t addr[6])
+{
+ int i;
+
+ for (i = 0; i < hci->scan_cache_count; i++) {
+ if (hci->scan_cache[i].addr_type == addr_type &&
+ !memcmp(hci->scan_cache[i].addr, addr, 6))
+ return false;
+ }
+
+ if (hci->scan_cache_count >= SCAN_CACHE_SIZE)
+ return true;
+
+ hci->scan_cache[hci->scan_cache_count].addr_type = addr_type;
+ memcpy(hci->scan_cache[hci->scan_cache_count].addr, addr, 6);
+ hci->scan_cache_count++;
+
+ return true;
+}
+
static void send_event(struct bt_le *hci, uint8_t event,
void *data, uint8_t size)
{
@@ -857,6 +893,8 @@ static void cmd_le_set_scan_enable(struct bt_le *hci,
return;
}
+ clear_scan_cache(hci);
+
hci->le_scan_enable = cmd->enable;
hci->le_scan_filter_dup = cmd->filter_dup;
@@ -1436,6 +1474,12 @@ static void phy_recv_callback(uint16_t type, const void *data,
uint8_t buf[100];
struct bt_hci_evt_le_adv_report *evt = (void *) buf;
+ if (hci->le_scan_filter_dup) {
+ if (!add_to_scan_cache(hci, pkt->tx_addr_type,
+ pkt->tx_addr))
+ break;
+ }
+
memset(buf, 0, sizeof(buf));
evt->num_reports = 0x01;
evt->event_type = pkt->pdu_type;