forked from mutability/dump1090
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
icao_filter.[ch] from the experimental branch.
- Loading branch information
1 parent
270a22e
commit 0433ed3
Showing
7 changed files
with
197 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Part of dump1090, a Mode S message decoder for RTLSDR devices. | ||
// | ||
// icao_filter.c: hashtable for ICAO addresses | ||
// | ||
// Copyright (c) 2014,2015 Oliver Jowett <oliver@mutability.co.uk> | ||
// | ||
// This file is free software: you may copy, redistribute and/or modify it | ||
// under the terms of the GNU General Public License as published by the | ||
// Free Software Foundation, either version 2 of the License, or (at your | ||
// option) any later version. | ||
// | ||
// This file is distributed in the hope that it will be useful, but | ||
// WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
#include "dump1090.h" | ||
|
||
// hash table size, must be a power of two: | ||
#define ICAO_FILTER_SIZE 4096 | ||
|
||
// Seconds between filter expiry flips: | ||
#define MODES_ICAO_FILTER_TTL 60 | ||
|
||
// Open-addressed hash table with linear probing. | ||
// We store each address twice to handle Address/Parity and Data/Parity | ||
// which need to match on a partial address (top 16 bits only). | ||
|
||
// Maintain two tables and switch between them to age out entries. | ||
|
||
static uint32_t icao_filter_a[ICAO_FILTER_SIZE]; | ||
static uint32_t icao_filter_b[ICAO_FILTER_SIZE]; | ||
static uint32_t *icao_filter_active; | ||
|
||
static uint32_t icaoHash(uint32_t a) | ||
{ | ||
// Jenkins one-at-a-time hash, unrolled for 3 bytes | ||
uint32_t hash = 0; | ||
|
||
hash += a & 0xff; | ||
hash += hash << 10; | ||
hash ^= hash >> 6; | ||
|
||
hash += (a >> 8) & 0xff; | ||
hash += (hash << 10); | ||
hash ^= (hash >> 6); | ||
|
||
hash += (a >> 16) & 0xff; | ||
hash += (hash << 10); | ||
hash ^= (hash >> 6); | ||
|
||
hash += (hash << 3); | ||
hash ^= (hash >> 11); | ||
hash += (hash << 15); | ||
|
||
return hash & (ICAO_FILTER_SIZE-1); | ||
} | ||
|
||
void icaoFilterInit() | ||
{ | ||
memset(icao_filter_a, 0, sizeof(icao_filter_a)); | ||
memset(icao_filter_b, 0, sizeof(icao_filter_b)); | ||
icao_filter_active = icao_filter_a; | ||
} | ||
|
||
void icaoFilterAdd(uint32_t addr) | ||
{ | ||
uint32_t h = icaoHash(addr); | ||
while (icao_filter_active[h] && icao_filter_active[h] != addr) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (!icao_filter_active[h]) | ||
icao_filter_active[h] = addr; | ||
|
||
// also add with a zeroed top byte, for handling DF20/21 with Data Parity | ||
h = icaoHash(addr & 0x00ffff); | ||
while (icao_filter_active[h] && (icao_filter_active[h] & 0x00ffff) != (addr & 0x00ffff)) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (!icao_filter_active[h]) | ||
icao_filter_active[h] = addr; | ||
} | ||
|
||
int icaoFilterTest(uint32_t addr) | ||
{ | ||
uint32_t h, h0; | ||
|
||
h0 = h = icaoHash(addr); | ||
while (icao_filter_a[h] && icao_filter_a[h] != addr) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (icao_filter_a[h]) | ||
return 1; | ||
|
||
h = h0; | ||
while (icao_filter_b[h] && icao_filter_b[h] != addr) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (icao_filter_b[h]) | ||
return 1; | ||
|
||
return 0; | ||
} | ||
|
||
uint32_t icaoFilterTestFuzzy(uint32_t partial) | ||
{ | ||
uint32_t h, h0; | ||
|
||
partial &= 0x00ffff; | ||
h0 = h = icaoHash(partial); | ||
while (icao_filter_a[h] && (icao_filter_a[h] & 0x00ffff) != partial) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (icao_filter_a[h]) | ||
return icao_filter_a[h]; | ||
|
||
h = h0; | ||
while (icao_filter_b[h] && (icao_filter_b[h] & 0x00ffff) != partial) | ||
h = (h+1) & (ICAO_FILTER_SIZE-1); | ||
if (icao_filter_b[h]) | ||
return icao_filter_b[h]; | ||
|
||
return 0; | ||
} | ||
|
||
// call this periodically: | ||
void icaoFilterExpire() | ||
{ | ||
static time_t next_flip = 0; | ||
time_t now = time(NULL); | ||
|
||
if (now >= next_flip) { | ||
if (icao_filter_active == icao_filter_a) { | ||
memset(icao_filter_b, 0, sizeof(icao_filter_b)); | ||
icao_filter_active = icao_filter_b; | ||
} else { | ||
memset(icao_filter_a, 0, sizeof(icao_filter_a)); | ||
icao_filter_active = icao_filter_a; | ||
} | ||
next_flip = now + MODES_ICAO_FILTER_TTL; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Part of dump1090, a Mode S message decoder for RTLSDR devices. | ||
// | ||
// icao_filter.c: prototypes for ICAO address hashtable | ||
// | ||
// Copyright (c) 2014,2015 Oliver Jowett <oliver@mutability.co.uk> | ||
// | ||
// This file is free software: you may copy, redistribute and/or modify it | ||
// under the terms of the GNU General Public License as published by the | ||
// Free Software Foundation, either version 2 of the License, or (at your | ||
// option) any later version. | ||
// | ||
// This file is distributed in the hope that it will be useful, but | ||
// WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
// General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
#ifndef DUMP1090_ICAO_FILTER_H | ||
#define DUMP1090_ICAO_FILTER_H | ||
|
||
// Call once: | ||
void icaoFilterInit(); | ||
|
||
// Add an address to the filter | ||
void icaoFilterAdd(uint32_t addr); | ||
|
||
// Test if the given address matches the filter | ||
int icaoFilterTest(uint32_t addr); | ||
|
||
// Test if the top 16 bits match any previously added address. | ||
// If they do, returns an arbitrary one of the matched | ||
// addresses. Returns 0 on failure. | ||
uint32_t icaoFilterTestFuzzy(uint32_t partial); | ||
|
||
// Call this periodically to allow the filter to expire | ||
// old entries. | ||
void icaoFilterExpire(); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters