diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2014-12-14 17:03:13 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-14 17:03:13 +0100 |
commit | 06159d7ab3202104b6345dac7f94ed714d74fcbc (patch) | |
tree | bbe4860f10c406178cbe83e71ead9f2fbcd32b3c /emulator/le.c | |
parent | 4b2318b60dd35198919dc601cb79253026b54586 (diff) | |
download | bluez-06159d7ab3202104b6345dac7f94ed714d74fcbc.tar.gz |
emulator: Add support for duplicate filtering during scanning
Diffstat (limited to 'emulator/le.c')
-rw-r--r-- | emulator/le.c | 44 |
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; |