From ebdba9351071330644fb9e47b888e13c54d2d4ed Mon Sep 17 00:00:00 2001 From: David Michaeli Date: Thu, 21 Apr 2022 13:04:08 +0300 Subject: [PATCH] ads-b message decoding and beutification --- examples/cpp/CMakeLists.txt | 1 + examples/cpp/build/CMakeFiles/Makefile2 | 4 +- .../caribou_dump1090.dir/CXX.includecache | 2 +- .../caribou_dump1090.dir/DependInfo.cmake | 1 + .../caribou_dump1090.dir/build.make | 19 +- .../caribou_dump1090.dir/cmake_clean.cmake | 1 + .../caribou_dump1090.dir/depend.internal | 3 + .../caribou_dump1090.dir/depend.make | 3 + .../CMakeFiles/caribou_dump1090.dir/link.txt | 2 +- .../caribou_dump1090.dir/progress.make | 1 + examples/cpp/build/CMakeFiles/progress.marks | 2 +- examples/cpp/build/Makefile | 30 + examples/cpp/build/caribou_dump1090 | Bin 343680 -> 39392 bytes examples/cpp/cpr.c | 369 ++++++ examples/cpp/cpr.h | 39 + examples/cpp/dump1090.cpp | 169 +-- examples/cpp/modes.c | 1173 ++++++++++------- examples/cpp/modes.h | 16 +- 18 files changed, 1259 insertions(+), 576 deletions(-) create mode 100644 examples/cpp/cpr.c create mode 100644 examples/cpp/cpr.h diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index e072fa2..59a2c13 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -20,6 +20,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) add_executable(caribou_dump1090 dump1090.cpp modes.c + cpr.c ) target_link_libraries(caribou_dump1090 SoapySDR iir_static) diff --git a/examples/cpp/build/CMakeFiles/Makefile2 b/examples/cpp/build/CMakeFiles/Makefile2 index d99620b..86dc577 100644 --- a/examples/cpp/build/CMakeFiles/Makefile2 +++ b/examples/cpp/build/CMakeFiles/Makefile2 @@ -93,12 +93,12 @@ clean: CMakeFiles/caribou_dump1090.dir/clean CMakeFiles/caribou_dump1090.dir/all: $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/depend $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/build - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles --progress-num=1,2,3 "Built target caribou_dump1090" + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --progress-dir=/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles --progress-num=1,2,3,4 "Built target caribou_dump1090" .PHONY : CMakeFiles/caribou_dump1090.dir/all # Build rule for subdir invocation for target. CMakeFiles/caribou_dump1090.dir/rule: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles 3 + $(CMAKE_COMMAND) -E cmake_progress_start /home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles 4 $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/caribou_dump1090.dir/all $(CMAKE_COMMAND) -E cmake_progress_start /home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles 0 .PHONY : CMakeFiles/caribou_dump1090.dir/rule diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/CXX.includecache b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/CXX.includecache index 5c4ce35..adbf9ed 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/CXX.includecache +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/CXX.includecache @@ -55,6 +55,6 @@ unistd.h - math.h - -sys/time.h +time.h - diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/DependInfo.cmake b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/DependInfo.cmake index 5ee87f3..5948bd0 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/DependInfo.cmake +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/DependInfo.cmake @@ -5,6 +5,7 @@ set(CMAKE_DEPENDS_LANGUAGES ) # The set of files for implicit dependencies of each language: set(CMAKE_DEPENDS_CHECK_C + "/home/pi/projects/cariboulite/examples/cpp/cpr.c" "/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/cpr.c.o" "/home/pi/projects/cariboulite/examples/cpp/modes.c" "/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/modes.c.o" ) set(CMAKE_C_COMPILER_ID "GNU") diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/build.make b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/build.make index d601ac5..78bb4dd 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/build.make +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/build.make @@ -102,19 +102,34 @@ CMakeFiles/caribou_dump1090.dir/modes.c.s: cmake_force @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/caribou_dump1090.dir/modes.c.s" /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/pi/projects/cariboulite/examples/cpp/modes.c -o CMakeFiles/caribou_dump1090.dir/modes.c.s +CMakeFiles/caribou_dump1090.dir/cpr.c.o: CMakeFiles/caribou_dump1090.dir/flags.make +CMakeFiles/caribou_dump1090.dir/cpr.c.o: ../cpr.c + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building C object CMakeFiles/caribou_dump1090.dir/cpr.c.o" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -o CMakeFiles/caribou_dump1090.dir/cpr.c.o -c /home/pi/projects/cariboulite/examples/cpp/cpr.c + +CMakeFiles/caribou_dump1090.dir/cpr.c.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/caribou_dump1090.dir/cpr.c.i" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/pi/projects/cariboulite/examples/cpp/cpr.c > CMakeFiles/caribou_dump1090.dir/cpr.c.i + +CMakeFiles/caribou_dump1090.dir/cpr.c.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/caribou_dump1090.dir/cpr.c.s" + /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/pi/projects/cariboulite/examples/cpp/cpr.c -o CMakeFiles/caribou_dump1090.dir/cpr.c.s + # Object files for target caribou_dump1090 caribou_dump1090_OBJECTS = \ "CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o" \ -"CMakeFiles/caribou_dump1090.dir/modes.c.o" +"CMakeFiles/caribou_dump1090.dir/modes.c.o" \ +"CMakeFiles/caribou_dump1090.dir/cpr.c.o" # External object files for target caribou_dump1090 caribou_dump1090_EXTERNAL_OBJECTS = caribou_dump1090: CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o caribou_dump1090: CMakeFiles/caribou_dump1090.dir/modes.c.o +caribou_dump1090: CMakeFiles/caribou_dump1090.dir/cpr.c.o caribou_dump1090: CMakeFiles/caribou_dump1090.dir/build.make caribou_dump1090: CMakeFiles/caribou_dump1090.dir/link.txt - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Linking CXX executable caribou_dump1090" + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/pi/projects/cariboulite/examples/cpp/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Linking CXX executable caribou_dump1090" $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/caribou_dump1090.dir/link.txt --verbose=$(VERBOSE) # Rule to build all files generated by this target. diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/cmake_clean.cmake b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/cmake_clean.cmake index 8074c57..f67849f 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/cmake_clean.cmake +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/cmake_clean.cmake @@ -1,4 +1,5 @@ file(REMOVE_RECURSE + "CMakeFiles/caribou_dump1090.dir/cpr.c.o" "CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o" "CMakeFiles/caribou_dump1090.dir/modes.c.o" "caribou_dump1090" diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.internal b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.internal index 5bf8fbc..627537e 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.internal +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.internal @@ -1,6 +1,9 @@ # CMAKE generated file: DO NOT EDIT! # Generated by "Unix Makefiles" Generator, CMake Version 3.18 +CMakeFiles/caribou_dump1090.dir/cpr.c.o + /home/pi/projects/cariboulite/examples/cpp/cpr.c + /home/pi/projects/cariboulite/examples/cpp/cpr.h CMakeFiles/caribou_dump1090.dir/modes.c.o /home/pi/projects/cariboulite/examples/cpp/modes.c /home/pi/projects/cariboulite/examples/cpp/modes.h diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.make b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.make index c5580a4..1ecbbdd 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.make +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/depend.make @@ -1,6 +1,9 @@ # CMAKE generated file: DO NOT EDIT! # Generated by "Unix Makefiles" Generator, CMake Version 3.18 +CMakeFiles/caribou_dump1090.dir/cpr.c.o: ../cpr.c +CMakeFiles/caribou_dump1090.dir/cpr.c.o: ../cpr.h + CMakeFiles/caribou_dump1090.dir/modes.c.o: ../modes.c CMakeFiles/caribou_dump1090.dir/modes.c.o: ../modes.h diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/link.txt b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/link.txt index 47c94e6..8b0b3f2 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/link.txt +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/link.txt @@ -1 +1 @@ -/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o CMakeFiles/caribou_dump1090.dir/modes.c.o -o caribou_dump1090 -lSoapySDR -liir_static +/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o CMakeFiles/caribou_dump1090.dir/modes.c.o CMakeFiles/caribou_dump1090.dir/cpr.c.o -o caribou_dump1090 -lSoapySDR -liir_static diff --git a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/progress.make b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/progress.make index 6a9dc74..a69a57e 100644 --- a/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/progress.make +++ b/examples/cpp/build/CMakeFiles/caribou_dump1090.dir/progress.make @@ -1,4 +1,5 @@ CMAKE_PROGRESS_1 = 1 CMAKE_PROGRESS_2 = 2 CMAKE_PROGRESS_3 = 3 +CMAKE_PROGRESS_4 = 4 diff --git a/examples/cpp/build/CMakeFiles/progress.marks b/examples/cpp/build/CMakeFiles/progress.marks index 00750ed..b8626c4 100644 --- a/examples/cpp/build/CMakeFiles/progress.marks +++ b/examples/cpp/build/CMakeFiles/progress.marks @@ -1 +1 @@ -3 +4 diff --git a/examples/cpp/build/Makefile b/examples/cpp/build/Makefile index f1e8062..2b09ae9 100644 --- a/examples/cpp/build/Makefile +++ b/examples/cpp/build/Makefile @@ -142,6 +142,33 @@ caribou_dump1090/fast: $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/build .PHONY : caribou_dump1090/fast +cpr.o: cpr.c.o + +.PHONY : cpr.o + +# target to build an object file +cpr.c.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/cpr.c.o +.PHONY : cpr.c.o + +cpr.i: cpr.c.i + +.PHONY : cpr.i + +# target to preprocess a source file +cpr.c.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/cpr.c.i +.PHONY : cpr.c.i + +cpr.s: cpr.c.s + +.PHONY : cpr.s + +# target to generate assembly for a file +cpr.c.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caribou_dump1090.dir/build.make CMakeFiles/caribou_dump1090.dir/cpr.c.s +.PHONY : cpr.c.s + dump1090.o: dump1090.cpp.o .PHONY : dump1090.o @@ -205,6 +232,9 @@ help: @echo "... edit_cache" @echo "... rebuild_cache" @echo "... caribou_dump1090" + @echo "... cpr.o" + @echo "... cpr.i" + @echo "... cpr.s" @echo "... dump1090.o" @echo "... dump1090.i" @echo "... dump1090.s" diff --git a/examples/cpp/build/caribou_dump1090 b/examples/cpp/build/caribou_dump1090 index c299d0fe6bfad053237953a2c5b6d542d323656e..5ea134b35242ed3b6bbf2056cf687cc048b2e675 100755 GIT binary patch literal 39392 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 diff --git a/examples/cpp/cpr.c b/examples/cpp/cpr.c new file mode 100644 index 0000000..c2e14ff --- /dev/null +++ b/examples/cpp/cpr.c @@ -0,0 +1,369 @@ +// Part of dump1090, a Mode S message decoder for RTLSDR devices. +// +// cpr.c - Compact Position Reporting decoder and tests +// +// Copyright (c) 2014,2015 Oliver Jowett +// +// 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 . + +// This file incorporates work covered by the following copyright and +// permission notice: +// +// Copyright (C) 2012 by Salvatore Sanfilippo +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "cpr.h" + +#include +#include + +// +//========================================================================= +// +// Always positive MOD operation, used for CPR decoding. +// +static int cprModInt(int a, int b) { + int res = a % b; + if (res < 0) res += b; + return res; +} + +static double cprModDouble(double a, double b) { + double res = fmod(a, b); + if (res < 0) res += b; + return res; +} + +// +//========================================================================= +// +// The NL function uses the precomputed table from 1090-WP-9-14 +// +static int cprNLFunction(double lat) { + if (lat < 0) lat = -lat; // Table is simmetric about the equator + if (lat < 10.47047130) return 59; + if (lat < 14.82817437) return 58; + if (lat < 18.18626357) return 57; + if (lat < 21.02939493) return 56; + if (lat < 23.54504487) return 55; + if (lat < 25.82924707) return 54; + if (lat < 27.93898710) return 53; + if (lat < 29.91135686) return 52; + if (lat < 31.77209708) return 51; + if (lat < 33.53993436) return 50; + if (lat < 35.22899598) return 49; + if (lat < 36.85025108) return 48; + if (lat < 38.41241892) return 47; + if (lat < 39.92256684) return 46; + if (lat < 41.38651832) return 45; + if (lat < 42.80914012) return 44; + if (lat < 44.19454951) return 43; + if (lat < 45.54626723) return 42; + if (lat < 46.86733252) return 41; + if (lat < 48.16039128) return 40; + if (lat < 49.42776439) return 39; + if (lat < 50.67150166) return 38; + if (lat < 51.89342469) return 37; + if (lat < 53.09516153) return 36; + if (lat < 54.27817472) return 35; + if (lat < 55.44378444) return 34; + if (lat < 56.59318756) return 33; + if (lat < 57.72747354) return 32; + if (lat < 58.84763776) return 31; + if (lat < 59.95459277) return 30; + if (lat < 61.04917774) return 29; + if (lat < 62.13216659) return 28; + if (lat < 63.20427479) return 27; + if (lat < 64.26616523) return 26; + if (lat < 65.31845310) return 25; + if (lat < 66.36171008) return 24; + if (lat < 67.39646774) return 23; + if (lat < 68.42322022) return 22; + if (lat < 69.44242631) return 21; + if (lat < 70.45451075) return 20; + if (lat < 71.45986473) return 19; + if (lat < 72.45884545) return 18; + if (lat < 73.45177442) return 17; + if (lat < 74.43893416) return 16; + if (lat < 75.42056257) return 15; + if (lat < 76.39684391) return 14; + if (lat < 77.36789461) return 13; + if (lat < 78.33374083) return 12; + if (lat < 79.29428225) return 11; + if (lat < 80.24923213) return 10; + if (lat < 81.19801349) return 9; + if (lat < 82.13956981) return 8; + if (lat < 83.07199445) return 7; + if (lat < 83.99173563) return 6; + if (lat < 84.89166191) return 5; + if (lat < 85.75541621) return 4; + if (lat < 86.53536998) return 3; + if (lat < 87.00000000) return 2; + else return 1; +} +// +//========================================================================= +// +static int cprNFunction(double lat, int fflag) { + int nl = cprNLFunction(lat) - (fflag ? 1 : 0); + if (nl < 1) nl = 1; + return nl; +} +// +//========================================================================= +// +static double cprDlonFunction(double lat, int fflag, int surface) { + return (surface ? 90.0 : 360.0) / cprNFunction(lat, fflag); +} +// +//========================================================================= +// +// This algorithm comes from: +// http://www.lll.lu/~edward/edward/adsb/DecodingADSBposition.html. +// +// A few remarks: +// 1) 131072 is 2^17 since CPR latitude and longitude are encoded in 17 bits. +// +int decodeCPRairborne(int even_cprlat, int even_cprlon, + int odd_cprlat, int odd_cprlon, + int fflag, + double *out_lat, double *out_lon) +{ + double AirDlat0 = 360.0 / 60.0; + double AirDlat1 = 360.0 / 59.0; + double lat0 = even_cprlat; + double lat1 = odd_cprlat; + double lon0 = even_cprlon; + double lon1 = odd_cprlon; + + double rlat, rlon; + + // Compute the Latitude Index "j" + int j = (int) floor(((59*lat0 - 60*lat1) / 131072) + 0.5); + double rlat0 = AirDlat0 * (cprModInt(j,60) + lat0 / 131072); + double rlat1 = AirDlat1 * (cprModInt(j,59) + lat1 / 131072); + + if (rlat0 >= 270) rlat0 -= 360; + if (rlat1 >= 270) rlat1 -= 360; + + // Check to see that the latitude is in range: -90 .. +90 + if (rlat0 < -90 || rlat0 > 90 || rlat1 < -90 || rlat1 > 90) + return (-2); // bad data + + // Check that both are in the same latitude zone, or abort. + if (cprNLFunction(rlat0) != cprNLFunction(rlat1)) + return (-1); // positions crossed a latitude zone, try again later + + // Compute ni and the Longitude Index "m" + if (fflag) { // Use odd packet. + int ni = cprNFunction(rlat1,1); + int m = (int) floor((((lon0 * (cprNLFunction(rlat1)-1)) - + (lon1 * cprNLFunction(rlat1))) / 131072.0) + 0.5); + rlon = cprDlonFunction(rlat1, 1, 0) * (cprModInt(m, ni)+lon1/131072); + rlat = rlat1; + } else { // Use even packet. + int ni = cprNFunction(rlat0,0); + int m = (int) floor((((lon0 * (cprNLFunction(rlat0)-1)) - + (lon1 * cprNLFunction(rlat0))) / 131072) + 0.5); + rlon = cprDlonFunction(rlat0, 0, 0) * (cprModInt(m, ni)+lon0/131072); + rlat = rlat0; + } + + // Renormalize to -180 .. +180 + rlon -= floor( (rlon + 180) / 360 ) * 360; + + *out_lat = rlat; + *out_lon = rlon; + + return 0; +} + +int decodeCPRsurface(double reflat, double reflon, + int even_cprlat, int even_cprlon, + int odd_cprlat, int odd_cprlon, + int fflag, + double *out_lat, double *out_lon) +{ + double AirDlat0 = 90.0 / 60.0; + double AirDlat1 = 90.0 / 59.0; + double lat0 = even_cprlat; + double lat1 = odd_cprlat; + double lon0 = even_cprlon; + double lon1 = odd_cprlon; + double rlon, rlat; + + // Compute the Latitude Index "j" + int j = (int) floor(((59*lat0 - 60*lat1) / 131072) + 0.5); + double rlat0 = AirDlat0 * (cprModInt(j,60) + lat0 / 131072); + double rlat1 = AirDlat1 * (cprModInt(j,59) + lat1 / 131072); + + // Pick the quadrant that's closest to the reference location - + // this is not necessarily the same quadrant that contains the + // reference location. + // + // There are also only two valid quadrants: -90..0 and 0..90; + // no correct message would try to encoding a latitude in the + // ranges -180..-90 and 90..180. + // + // If the computed latitude is more than 45 degrees north of + // the reference latitude (using the northern hemisphere + // solution), then the southern hemisphere solution will be + // closer to the refernce latitude. + // + // e.g. reflat=0, rlat=44, use rlat=44 + // reflat=0, rlat=46, use rlat=46-90 = -44 + // reflat=40, rlat=84, use rlat=84 + // reflat=40, rlat=86, use rlat=86-90 = -4 + // reflat=-40, rlat=4, use rlat=4 + // reflat=-40, rlat=6, use rlat=6-90 = -84 + + // As a special case, -90, 0 and +90 all encode to zero, so + // there's a little extra work to do there. + + if (rlat0 == 0) { + if (reflat < -45) + rlat0 = -90; + else if (reflat > 45) + rlat0 = 90; + } else if ((rlat0 - reflat) > 45) { + rlat0 -= 90; + } + + if (rlat1 == 0) { + if (reflat < -45) + rlat1 = -90; + else if (reflat > 45) + rlat1 = 90; + } else if ((rlat1 - reflat) > 45) { + rlat1 -= 90; + } + + // Check to see that the latitude is in range: -90 .. +90 + if (rlat0 < -90 || rlat0 > 90 || rlat1 < -90 || rlat1 > 90) + return (-2); // bad data + + // Check that both are in the same latitude zone, or abort. + if (cprNLFunction(rlat0) != cprNLFunction(rlat1)) + return (-1); // positions crossed a latitude zone, try again later + + // Compute ni and the Longitude Index "m" + if (fflag) { // Use odd packet. + int ni = cprNFunction(rlat1,1); + int m = (int) floor((((lon0 * (cprNLFunction(rlat1)-1)) - + (lon1 * cprNLFunction(rlat1))) / 131072.0) + 0.5); + rlon = cprDlonFunction(rlat1, 1, 1) * (cprModInt(m, ni)+lon1/131072); + rlat = rlat1; + } else { // Use even packet. + int ni = cprNFunction(rlat0,0); + int m = (int) floor((((lon0 * (cprNLFunction(rlat0)-1)) - + (lon1 * cprNLFunction(rlat0))) / 131072) + 0.5); + rlon = cprDlonFunction(rlat0, 0, 1) * (cprModInt(m, ni)+lon0/131072); + rlat = rlat0; + } + + // Pick the quadrant that's closest to the reference location - + // this is not necessarily the same quadrant that contains the + // reference location. Unlike the latitude case, all four + // quadrants are valid. + + // if reflon is more than 45 degrees away, move some multiple of 90 degrees towards it + rlon += floor( (reflon - rlon + 45) / 90 ) * 90; // this might move us outside (-180..+180), we fix this below + + // Renormalize to -180 .. +180 + rlon -= floor( (rlon + 180) / 360 ) * 360; + + *out_lat = rlat; + *out_lon = rlon; + return 0; +} + +// +//========================================================================= +// +// This algorithm comes from: +// 1090-WP29-07-Draft_CPR101 (which also defines decodeCPR() ) +// +// Despite what the earlier comment here said, we should *not* be using trunc(). +// See Figure 5-5 / 5-6 and note that floor is applied to (0.5 + fRP - fEP), not +// directly to (fRP - fEP). Eq 38 is correct. +// +int decodeCPRrelative(double reflat, double reflon, + int cprlat, int cprlon, + int fflag, int surface, + double *out_lat, double *out_lon) +{ + double AirDlat; + double AirDlon; + double fractional_lat = cprlat / 131072.0; + double fractional_lon = cprlon / 131072.0; + double rlon, rlat; + int j,m; + + AirDlat = (surface ? 90.0 : 360.0) / (fflag ? 59.0 : 60.0); + + // Compute the Latitude Index "j" + j = (int) (floor(reflat/AirDlat) + + floor(0.5 + cprModDouble(reflat, AirDlat)/AirDlat - fractional_lat)); + rlat = AirDlat * (j + fractional_lat); + if (rlat >= 270) rlat -= 360; + + // Check to see that the latitude is in range: -90 .. +90 + if (rlat < -90 || rlat > 90) { + return (-1); // Time to give up - Latitude error + } + + // Check to see that answer is reasonable - ie no more than 1/2 cell away + if (fabs(rlat - reflat) > (AirDlat/2)) { + return (-1); // Time to give up - Latitude error + } + + // Compute the Longitude Index "m" + AirDlon = cprDlonFunction(rlat, fflag, surface); + m = (int) (floor(reflon/AirDlon) + + floor(0.5 + cprModDouble(reflon, AirDlon)/AirDlon - fractional_lon)); + rlon = AirDlon * (m + fractional_lon); + if (rlon > 180) rlon -= 360; + + // Check to see that answer is reasonable - ie no more than 1/2 cell away + if (fabs(rlon - reflon) > (AirDlon/2)) + return (-1); // Time to give up - Longitude error + + *out_lat = rlat; + *out_lon = rlon; + return (0); +} diff --git a/examples/cpp/cpr.h b/examples/cpp/cpr.h new file mode 100644 index 0000000..65f4fa4 --- /dev/null +++ b/examples/cpp/cpr.h @@ -0,0 +1,39 @@ +// Part of dump1090, a Mode S message decoder for RTLSDR devices. +// +// cpr.h - Compact Position Reporting prototypes +// +// Copyright (c) 2014,2015 Oliver Jowett +// +// 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 . + +#ifndef DUMP1090_CPR_H +#define DUMP1090_CPR_H + +int decodeCPRairborne(int even_cprlat, int even_cprlon, + int odd_cprlat, int odd_cprlon, + int fflag, + double *out_lat, double *out_lon); + +int decodeCPRsurface(double reflat, double reflon, + int even_cprlat, int even_cprlon, + int odd_cprlat, int odd_cprlon, + int fflag, + double *out_lat, double *out_lon); + +int decodeCPRrelative(double reflat, double reflon, + int cprlat, int cprlon, + int fflag, int surface, + double *out_lat, double *out_lon); + +#endif diff --git a/examples/cpp/dump1090.cpp b/examples/cpp/dump1090.cpp index 497d4f4..d7ca6b6 100644 --- a/examples/cpp/dump1090.cpp +++ b/examples/cpp/dump1090.cpp @@ -19,9 +19,7 @@ #include "modes.h" -/*********************************************************************** - * Print the banner - **********************************************************************/ +//================================================================================= static void printBanner(void) { std::cout << "######################################################" << std::endl; @@ -30,86 +28,21 @@ static void printBanner(void) std::cout << std::endl; } -/*********************************************************************** - * Find devices and print args - **********************************************************************/ -static int findDevices(const std::string &argStr) -{ - const auto results = SoapySDR::Device::enumerate(argStr); - std::cout << "Found " << results.size() << " devices" << std::endl; - - for (size_t i = 0; i < results.size(); i++) - { - std::cout << "Found device " << i << std::endl; - for (const auto &it : results[i]) - { - std::cout << " " << it.first << " = " << it.second << std::endl; - } - std::cout << std::endl; - } - if (results.empty()) std::cerr << "No devices found! " << argStr << std::endl; - else std::cout << std::endl; - - return results.empty()?EXIT_FAILURE:EXIT_SUCCESS; -} - -/*********************************************************************** - * Run the stream function - **********************************************************************/ +//================================================================================= static sig_atomic_t loopDone = false; static void sigIntHandler(const int) { loopDone = true; } +//================================================================================= void onModeSMessage(mode_s_t *self, struct mode_s_msg *mm) { - printf("Got message from flight %s\n", mm->flight); - - printf(" HEADER: #Bits: %d, Type: %d, CRCOK: %d, ECC: %d, ICAO_ADDR:%02X%02X%02X, PHC: %d, CAP: %08X\n", - mm->msgbits, // Number of bits in message - mm->msgtype, // Downlink format # - mm->crcok, // True if CRC was valid - mm->errorbit, // Bit corrected. -1 if no bit corrected. - mm->aa1, mm->aa2, mm->aa3, // ICAO Address bytes 1 2 and 3 - mm->phase_corrected, // True if phase correction was applied. - mm->ca); // Responder capabilities. - - - printf(" DATA1: MsgTp: %d, MsgSTp: %d, HdVld: %d, Hd: %d, AirCftTp:%d, FFlg: %d, UtcSync: %d, Lat: %d, Lon: %d, Dir W/S: %d/%d\n" - " DATA2: Vel (W/S): %d/%d, Vel: %d, VertRt (Src/Sgn/Rt): %d/%d/%d, Alt: %d, Stat: %d, Id: %08X, Unt: %d\n\n", - mm->metype, // Extended squitter message type. - mm->mesub, // Extended squitter message subtype. - mm->heading_is_valid, // heading_is_valid - mm->heading, // heading - mm->aircraft_type, // aircraft_type - mm->fflag, // 1 = Odd, 0 = Even CPR message. - mm->tflag, // UTC synchronized? - mm->raw_latitude, // Non decoded latitude - mm->raw_longitude, // Non decoded raw_longitude - mm->ew_dir, // 0 = East, 1 = West. - mm->ns_dir, // 0 = North, 1 = South. - mm->ew_velocity, // E/W velocity. - mm->ns_velocity, // N/S velocity. - mm->velocity, - mm->vert_rate_source, // Vertical rate source. - mm->vert_rate_sign, // Vertical rate sign. - mm->vert_rate, // // Vertical rate. - mm->altitude, - mm->fs, // Flight status for DF4,5,20,21 - mm->identity, // 13 bits identity (Squawk). - mm->unit); -} - -#define FILT_ORDER 6 -Iir::Butterworth::LowPass filt; - -void makeFilter(double fs, double cutoff) -{ - try {filt.setup(fs, cutoff);} - catch (...) {printf("Filter Setup Exception!\n");} + mode_s_display_message(mm); + printf("\n"); } +//================================================================================= // Turn I/Q samples pointed by `data` into the magnitude vector pointed by `mag` void MagnitudeVectorDownSample(short *data, uint16_t *mag, uint32_t size) { @@ -126,50 +59,50 @@ void MagnitudeVectorDownSample(short *data, uint16_t *mag, uint32_t size) } } -void runSoapyProcess( - SoapySDR::Device *device, - SoapySDR::Stream *stream, - const int direction, - const size_t numChans, - const size_t elemSize) +//================================================================================= +void runSoapyProcess( SoapySDR::Device *device, + SoapySDR::Stream *stream, + const size_t elemSize) { - //allocate buffers for the stream read/write + // allocate buffers for the stream read/write const size_t numElems = device->getStreamMTU(stream); - int16_t* buff = (int16_t*)malloc (2*sizeof(int16_t)*numElems); // complex 16 bit samples + int16_t* buff = (int16_t*)malloc(2*sizeof(int16_t)*numElems); // complex 16 bit samples uint16_t* mag = (uint16_t*)malloc(sizeof(uint16_t)*numElems); - // MODE-S Stuff + // MODE-S mode_s_t state; mode_s_init(&state); - makeFilter(4e6, 50e3); std::cout << "Starting stream loop, press Ctrl+C to exit..." << std::endl; device->activateStream(stream); signal(SIGINT, sigIntHandler); + + // Main Processing Loop while (not loopDone) { - int ret = 0; - int flags = 0; long long timeUS = numElems; - ret = device->readStream(stream, (void* const*)&buff, numElems, flags, timeUS); - - if (ret == SOAPY_SDR_TIMEOUT) continue; - if (ret == SOAPY_SDR_OVERFLOW) - { - //overflows++; - continue; - } - if (ret == SOAPY_SDR_UNDERFLOW) - { - //underflows++; - continue; - } - if (ret < 0) + int flags = 0; + int ret = device->readStream(stream, (void* const*)&buff, numElems, flags, timeUS); + if (ret < 0) { std::cerr << "Unexpected stream error " << ret << std::endl; break; } + switch (ret) + { + case SOAPY_SDR_TIMEOUT: continue; + case SOAPY_SDR_OVERFLOW: + //overflows++; + continue; + case SOAPY_SDR_UNDERFLOW: + //underflows++; + continue; + default: + break; + } + + // All is good - proceed to DSP // compute the magnitude of the signal MagnitudeVectorDownSample(buff, mag, ret); @@ -178,6 +111,10 @@ void runSoapyProcess( } device->deactivateStream(stream); + + // free memory + free(buff); + free(mag); } @@ -187,40 +124,37 @@ void runSoapyProcess( int main(int argc, char *argv[]) { SoapySDR::ModuleManager mm(false); - SoapySDR::Device *device(nullptr); std::vector channels; std::string argStr = "driver=Cariboulite,channel=HiF"; double fullScale = 0.0; - double freq = 1090.0e6; - //double freq = 1090e6; printBanner(); try { device = SoapySDR::Device::make(argStr); - channels.push_back(0); - // set the sample rate - device->setSampleRate(SOAPY_SDR_RX, channels[0], 4e6); - device->setBandwidth(SOAPY_SDR_RX, channels[0], 2500e5); - device->setGainMode(SOAPY_SDR_RX, channels[0], false); - device->setGain(SOAPY_SDR_RX, channels[0], 50); - device->setFrequency(SOAPY_SDR_RX, channels[0], freq); + // set the sample rate, frequency, ... + device->setSampleRate(SOAPY_SDR_RX, 0, 4e6); + device->setBandwidth(SOAPY_SDR_RX, 0, 100e5); + device->setGainMode(SOAPY_SDR_RX, 0, false); + device->setGain(SOAPY_SDR_RX, 0, 50); + device->setFrequency(SOAPY_SDR_RX, 0, 1090e6); - //create the stream, use the native format - const auto format = device->getNativeStreamFormat(SOAPY_SDR_RX, channels.front(), fullScale); + // create the stream, use the native format + const auto format = device->getNativeStreamFormat(SOAPY_SDR_RX, 0, fullScale); const size_t elemSize = SoapySDR::formatToSize(format); auto stream = device->setupStream(SOAPY_SDR_RX, format, channels); - //run the rate test one setup is complete - std::cout << "Stream format: " << format << std::endl; - std::cout << "Num channels: " << channels.size() << std::endl; - std::cout << "Element size: " << elemSize << " bytes" << std::endl; - runSoapyProcess(device, stream, SOAPY_SDR_RX, channels.size(), elemSize); + // run the rate test one setup is complete + std::cout << "Running Soapy process with CaribouLite Config:" << std::endl; + std::cout << " Stream format: " << format << std::endl; + std::cout << " Channel: HiF" << std::endl; + std::cout << " Sample size: " << elemSize << " bytes" << std::endl; + runSoapyProcess(device, stream, elemSize); - //cleanup stream and device + // cleanup stream and device device->closeStream(stream); SoapySDR::Device::unmake(device); } @@ -232,6 +166,5 @@ int main(int argc, char *argv[]) } std::cout << std::endl; - return 0; } diff --git a/examples/cpp/modes.c b/examples/cpp/modes.c index 9c35187..0f3b4f6 100644 --- a/examples/cpp/modes.c +++ b/examples/cpp/modes.c @@ -1,53 +1,249 @@ /* - * Source of file: https://github.com/watson/libmodes + * Modified source file by David Michaeli @ CaribouLabs Ltd. Apr. 2022 + * Based on source of file: https://github.com/watson/libmodes * Author: Thomas Watson (@watson) * Contact: w@tson.dk / https://twitter.com/wa7son * License: BSD-2-Clause */ #include "modes.h" +#include -#define MODE_S_PREAMBLE_US 8 // microseconds +// ========================================================================== +#define MODE_S_PREAMBLE_US 8 // microseconds #define MODE_S_LONG_MSG_BITS 112 #define MODE_S_SHORT_MSG_BITS 56 #define MODE_S_FULL_LEN (MODE_S_PREAMBLE_US+MODE_S_LONG_MSG_BITS) - -#define MODE_S_ICAO_CACHE_TTL 60 // Time to live of cached addresses. +#define MODE_S_UNIT_METERS 1 +#define MODE_S_ICAO_CACHE_TTL 60 // Time to live of cached addresses. static uint16_t maglut[129*129*2]; static int maglut_initialized = 0; -// =============================== Initialization =========================== +// ========================================================================== +// Capability table +char *ca_str[8] = +{ + /* 0 */ "Level 1 (Survillance Only)", + /* 1 */ "Level 2 (DF0,4,5,11)", + /* 2 */ "Level 3 (DF0,4,5,11,20,21)", + /* 3 */ "Level 4 (DF0,4,5,11,20,21,24)", + /* 4 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on ground)", + /* 5 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne)", + /* 6 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7)", + /* 7 */ "Level 7 ???" +}; -void mode_s_init(mode_s_t *self) { - int i, q; +// ========================================================================== +// Flight status table +char *fs_str[8] = +{ + /* 0 */ "Normal, Airborne", + /* 1 */ "Normal, On the ground", + /* 2 */ "ALERT, Airborne", + /* 3 */ "ALERT, On the ground", + /* 4 */ "ALERT & Special Position Identification. Airborne or Ground", + /* 5 */ "Special Position Identification. Airborne or Ground", + /* 6 */ "Value 6 is not assigned", + /* 7 */ "Value 7 is not assigned" +}; - self->fix_errors = 1; - self->check_crc = 1; - self->aggressive = 0; +// ========================================================================== +// ME message type to description table. +char *me_str[] = +{ +}; - // Allocate the ICAO address cache. We use two uint32_t for every entry - // because it's a addr / timestamp pair for every entry - memset(&self->icao_cache, 0, sizeof(self->icao_cache)); +// ========================================================================== +char *getMEDescription(int metype, int mesub) +{ + char *mename = "Unknown"; - // Populate the I/Q -> Magnitude lookup table. It is used because sqrt or - // round may be expensive and may vary a lot depending on the libc used. - // - // We scale to 0-255 range multiplying by 1.4 in order to ensure that every - // different I/Q pair will result in a different magnitude value, not losing - // any resolution. - if (!maglut_initialized) { - for (i = 0; i <= 128; i++) { - for (q = 0; q <= 128; q++) { - maglut[i*129+q] = round(sqrt(i*i+q*q)*360); - } + if (metype >= 1 && metype <= 4) + mename = "Aircraft Identification and Category"; + else if (metype >= 5 && metype <= 8) + mename = "Surface Position"; + else if (metype >= 9 && metype <= 18) + mename = "Airborne Position (Baro Altitude)"; + else if (metype == 19 && mesub >=1 && mesub <= 4) + mename = "Airborne Velocity"; + else if (metype >= 20 && metype <= 22) + mename = "Airborne Position (GNSS Height)"; + else if (metype == 23 && mesub == 0) + mename = "Test Message"; + else if (metype == 24 && mesub == 1) + mename = "Surface System Status"; + else if (metype == 28 && mesub == 1) + mename = "Extended Squitter Aircraft Status (Emergency)"; + else if (metype == 28 && mesub == 2) + mename = "Extended Squitter Aircraft Status (1090ES TCAS RA)"; + else if (metype == 29 && (mesub == 0 || mesub == 1)) + mename = "Target State and Status Message"; + else if (metype == 31 && (mesub == 0 || mesub == 1)) + mename = "Aircraft Operational Status Message"; + return mename; +} + +// ========================================================================== +// This function gets a decoded Mode S Message and prints it on the screen +// in a human readable format +void mode_s_display_message(struct mode_s_msg *mm) +{ + int j; + + /* Show the raw message. */ + printf("*"); + for (j = 0; j < mm->msgbits/8; j++) + { + printf("%02x", mm->msg[j]); + } + printf(";\n"); + + printf("CRC: %06x (%s)\n", (int)mm->crc, mm->crcok ? "ok" : "wrong"); + if (mm->errorbit != -1) + { + printf("Single bit error fixed, bit %d\n", mm->errorbit); + } + + if (mm->msgtype == 0) + { + /* DF 0 */ + printf("DF 0: Short Air-Air Surveillance.\n"); + printf(" Altitude : %d %s\n", mm->altitude, + (mm->unit == MODE_S_UNIT_METERS) ? "meters" : "feet"); + printf(" ICAO Address : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3); } - maglut_initialized = 1; - } + else if (mm->msgtype == 4 || mm->msgtype == 20) + { + printf("DF %d: %s, Altitude Reply.\n", mm->msgtype, (mm->msgtype == 4) ? "Surveillance" : "Comm-B"); + printf(" Flight Status : %s\n", fs_str[mm->fs]); + printf(" DR : %d\n", mm->dr); + printf(" UM : %d\n", mm->um); + printf(" Altitude : %d %s\n", mm->altitude, (mm->unit == MODE_S_UNIT_METERS) ? "meters" : "feet"); + printf(" ICAO Address : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3); + + if (mm->msgtype == 20) + { + /* TODO: 56 bits DF20 MB additional field. */ + } + } + else if (mm->msgtype == 5 || mm->msgtype == 21) + { + printf("DF %d: %s, Identity Reply.\n", mm->msgtype, (mm->msgtype == 5) ? "Surveillance" : "Comm-B"); + printf(" Flight Status : %s\n", fs_str[mm->fs]); + printf(" DR : %d\n", mm->dr); + printf(" UM : %d\n", mm->um); + printf(" Squawk : %d\n", mm->identity); + printf(" ICAO Address : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3); + + if (mm->msgtype == 21) { + /* TODO: 56 bits DF21 MB additional field. */ + } + } + else if (mm->msgtype == 11) + { + /* DF 11 */ + printf("DF 11: All Call Reply.\n"); + printf(" Capability : %s\n", ca_str[mm->ca]); + printf(" ICAO Address: %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3); + } + else if (mm->msgtype == 17) + { + /* DF 17 */ + printf("DF 17: ADS-B message.\n"); + printf(" Capability : %d (%s)\n", mm->ca, ca_str[mm->ca]); + printf(" ICAO Address : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3); + printf(" Extended Squitter Type: %d\n", mm->metype); + printf(" Extended Squitter Sub : %d\n", mm->mesub); + printf(" Extended Squitter Name: %s\n", getMEDescription(mm->metype,mm->mesub)); + + /* Decode the extended squitter message. */ + if (mm->metype >= 1 && mm->metype <= 4) + { + /* Aircraft identification. */ + char *ac_type_str[4] = + { + "Aircraft Type D", + "Aircraft Type C", + "Aircraft Type B", + "Aircraft Type A" + }; + + printf(" Aircraft Type : %s\n", ac_type_str[mm->aircraft_type]); + printf(" Identification : %s\n", mm->flight); + } + else if (mm->metype >= 9 && mm->metype <= 18) + { + printf(" F flag : %s\n", mm->fflag ? "odd" : "even"); + printf(" T flag : %s\n", mm->tflag ? "UTC" : "non-UTC"); + printf(" Altitude : %d feet\n", mm->altitude); + printf(" Latitude : %d (not decoded)\n", mm->raw_latitude); + printf(" Longitude: %d (not decoded)\n", mm->raw_longitude); + } + else if (mm->metype == 19 && mm->mesub >= 1 && mm->mesub <= 4) + { + if (mm->mesub == 1 || mm->mesub == 2) + { + /* Velocity */ + printf(" EW direction : %d\n", mm->ew_dir); + printf(" EW velocity : %d\n", mm->ew_velocity); + printf(" NS direction : %d\n", mm->ns_dir); + printf(" NS velocity : %d\n", mm->ns_velocity); + printf(" Vertical rate src : %d\n", mm->vert_rate_source); + printf(" Vertical rate sign: %d\n", mm->vert_rate_sign); + printf(" Vertical rate : %d\n", mm->vert_rate); + } + else if (mm->mesub == 3 || mm->mesub == 4) + { + printf(" Heading status: %d", mm->heading_is_valid); + printf(" Heading: %d", mm->heading); + } + } + else + { + printf(" Unrecognized ME type: %d subtype: %d\n", mm->metype, mm->mesub); + } + } + else + { + printf("DF %d with good CRC received (decoding still not implemented).\n", + mm->msgtype); + } +} + +// =============================== Initialization =========================== +void mode_s_init(mode_s_t *self) +{ + int i, q; + + self->fix_errors = 1; + self->check_crc = 1; + self->aggressive = 0; + + // Allocate the ICAO address cache. We use two uint32_t for every entry + // because it's a addr / timestamp pair for every entry + memset(&self->icao_cache, 0, sizeof(self->icao_cache)); + + // Populate the I/Q -> Magnitude lookup table. It is used because sqrt or + // round may be expensive and may vary a lot depending on the libc used. + // + // We scale to 0-255 range multiplying by 1.4 in order to ensure that every + // different I/Q pair will result in a different magnitude value, not losing + // any resolution. + if (!maglut_initialized) + { + for (i = 0; i <= 128; i++) + { + for (q = 0; q <= 128; q++) + { + maglut[i*129+q] = round(sqrt(i*i+q*q)*360); + } + } + maglut_initialized = 1; + } } // ===================== Mode S detection and decoding ===================== - // Parity table for MODE S Messages. // // The table contains 112 elements, every element corresponds to a bit set in @@ -65,40 +261,44 @@ void mode_s_init(mode_s_t *self) { // Note: this function can be used with DF11 and DF17, other modes have the CRC // xored with the sender address as they are reply to interrogations, but a // casual listener can't split the address from the checksum. -uint32_t mode_s_checksum_table[] = { - 0x3935ea, 0x1c9af5, 0xf1b77e, 0x78dbbf, 0xc397db, 0x9e31e9, 0xb0e2f0, 0x587178, - 0x2c38bc, 0x161c5e, 0x0b0e2f, 0xfa7d13, 0x82c48d, 0xbe9842, 0x5f4c21, 0xd05c14, - 0x682e0a, 0x341705, 0xe5f186, 0x72f8c3, 0xc68665, 0x9cb936, 0x4e5c9b, 0xd8d449, - 0x939020, 0x49c810, 0x24e408, 0x127204, 0x093902, 0x049c81, 0xfdb444, 0x7eda22, - 0x3f6d11, 0xe04c8c, 0x702646, 0x381323, 0xe3f395, 0x8e03ce, 0x4701e7, 0xdc7af7, - 0x91c77f, 0xb719bb, 0xa476d9, 0xadc168, 0x56e0b4, 0x2b705a, 0x15b82d, 0xf52612, - 0x7a9309, 0xc2b380, 0x6159c0, 0x30ace0, 0x185670, 0x0c2b38, 0x06159c, 0x030ace, - 0x018567, 0xff38b7, 0x80665f, 0xbfc92b, 0xa01e91, 0xaff54c, 0x57faa6, 0x2bfd53, - 0xea04ad, 0x8af852, 0x457c29, 0xdd4410, 0x6ea208, 0x375104, 0x1ba882, 0x0dd441, - 0xf91024, 0x7c8812, 0x3e4409, 0xe0d800, 0x706c00, 0x383600, 0x1c1b00, 0x0e0d80, - 0x0706c0, 0x038360, 0x01c1b0, 0x00e0d8, 0x00706c, 0x003836, 0x001c1b, 0xfff409, - 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, - 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 +uint32_t mode_s_checksum_table[] = +{ + 0x3935ea, 0x1c9af5, 0xf1b77e, 0x78dbbf, 0xc397db, 0x9e31e9, 0xb0e2f0, 0x587178, + 0x2c38bc, 0x161c5e, 0x0b0e2f, 0xfa7d13, 0x82c48d, 0xbe9842, 0x5f4c21, 0xd05c14, + 0x682e0a, 0x341705, 0xe5f186, 0x72f8c3, 0xc68665, 0x9cb936, 0x4e5c9b, 0xd8d449, + 0x939020, 0x49c810, 0x24e408, 0x127204, 0x093902, 0x049c81, 0xfdb444, 0x7eda22, + 0x3f6d11, 0xe04c8c, 0x702646, 0x381323, 0xe3f395, 0x8e03ce, 0x4701e7, 0xdc7af7, + 0x91c77f, 0xb719bb, 0xa476d9, 0xadc168, 0x56e0b4, 0x2b705a, 0x15b82d, 0xf52612, + 0x7a9309, 0xc2b380, 0x6159c0, 0x30ace0, 0x185670, 0x0c2b38, 0x06159c, 0x030ace, + 0x018567, 0xff38b7, 0x80665f, 0xbfc92b, 0xa01e91, 0xaff54c, 0x57faa6, 0x2bfd53, + 0xea04ad, 0x8af852, 0x457c29, 0xdd4410, 0x6ea208, 0x375104, 0x1ba882, 0x0dd441, + 0xf91024, 0x7c8812, 0x3e4409, 0xe0d800, 0x706c00, 0x383600, 0x1c1b00, 0x0e0d80, + 0x0706c0, 0x038360, 0x01c1b0, 0x00e0d8, 0x00706c, 0x003836, 0x001c1b, 0xfff409, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 }; -uint32_t mode_s_checksum(unsigned char *msg, int bits) { - uint32_t crc = 0; - int offset = (bits == 112) ? 0 : (112-56); - int j; +// ========================================================================== +uint32_t mode_s_checksum(unsigned char *msg, int bits) +{ + uint32_t crc = 0; + int offset = (bits == 112) ? 0 : (112-56); + int j; - for(j = 0; j < bits; j++) { - int byte = j/8; - int bit = j%8; - int bitmask = 1 << (7-bit); + for(j = 0; j < bits; j++) + { + int byte = j/8; + int bit = j%8; + int bitmask = 1 << (7-bit); - // If bit is set, xor with corresponding table entry. - if (msg[byte] & bitmask) - crc ^= mode_s_checksum_table[j+offset]; - } - return crc; // 24 bit checksum. + // If bit is set, xor with corresponding table entry. + if (msg[byte] & bitmask) crc ^= mode_s_checksum_table[j+offset]; + } + return crc; // 24 bit checksum. } +// ========================================================================== // Given the Downlink Format (DF) of the message, return the message length in // bits. int mode_s_msg_len_by_type(int type) @@ -113,108 +313,125 @@ int mode_s_msg_len_by_type(int type) return MODE_S_SHORT_MSG_BITS; } +// ========================================================================== // Try to fix single bit errors using the checksum. On success modifies the // original buffer with the fixed version, and returns the position of the // error bit. Otherwise if fixing failed -1 is returned. -int fix_single_bit_errors(unsigned char *msg, int bits) { - int j; - unsigned char aux[MODE_S_LONG_MSG_BITS/8]; +int fix_single_bit_errors(unsigned char *msg, int bits) +{ + int j; + unsigned char aux[MODE_S_LONG_MSG_BITS/8]; - for (j = 0; j < bits; j++) { - int byte = j/8; - int bitmask = 1 << (7-(j%8)); - uint32_t crc1, crc2; + for (j = 0; j < bits; j++) + { + int byte = j/8; + int bitmask = 1 << (7-(j%8)); + uint32_t crc1, crc2; - memcpy(aux, msg, bits/8); - aux[byte] ^= bitmask; // Flip j-th bit. + memcpy(aux, msg, bits/8); + aux[byte] ^= bitmask; // Flip j-th bit. - crc1 = ((uint32_t)aux[(bits/8)-3] << 16) | - ((uint32_t)aux[(bits/8)-2] << 8) | - (uint32_t)aux[(bits/8)-1]; - crc2 = mode_s_checksum(aux, bits); + crc1 = ( (uint32_t)aux[(bits/8)-3] << 16) | + ((uint32_t)aux[(bits/8)-2] << 8) | + (uint32_t)aux[(bits/8)-1]; + crc2 = mode_s_checksum(aux, bits); - if (crc1 == crc2) { - // The error is fixed. Overwrite the original buffer with the - // corrected sequence, and returns the error bit position. - memcpy(msg, aux, bits/8); - return j; - } - } - return -1; + if (crc1 == crc2) + { + // The error is fixed. Overwrite the original buffer with the + // corrected sequence, and returns the error bit position. + memcpy(msg, aux, bits/8); + return j; + } + } + return -1; } +// ========================================================================== // Similar to fix_single_bit_errors() but try every possible two bit // combination. This is very slow and should be tried only against DF17 // messages that don't pass the checksum, and only in Aggressive Mode. -int fix_two_bits_errors(unsigned char *msg, int bits) { - int j, i; - unsigned char aux[MODE_S_LONG_MSG_BITS/8]; +int fix_two_bits_errors(unsigned char *msg, int bits) +{ + int j, i; + unsigned char aux[MODE_S_LONG_MSG_BITS/8]; - for (j = 0; j < bits; j++) { - int byte1 = j/8; - int bitmask1 = 1 << (7-(j%8)); + for (j = 0; j < bits; j++) + { + int byte1 = j/8; + int bitmask1 = 1 << (7-(j%8)); - // Don't check the same pairs multiple times, so i starts from j+1 - for (i = j+1; i < bits; i++) { - int byte2 = i/8; - int bitmask2 = 1 << (7-(i%8)); - uint32_t crc1, crc2; + // Don't check the same pairs multiple times, so i starts from j+1 + for (i = j+1; i < bits; i++) + { + int byte2 = i/8; + int bitmask2 = 1 << (7-(i%8)); + uint32_t crc1, crc2; - memcpy(aux, msg, bits/8); + memcpy(aux, msg, bits/8); - aux[byte1] ^= bitmask1; // Flip j-th bit. - aux[byte2] ^= bitmask2; // Flip i-th bit. + aux[byte1] ^= bitmask1; // Flip j-th bit. + aux[byte2] ^= bitmask2; // Flip i-th bit. - crc1 = ((uint32_t)aux[(bits/8)-3] << 16) | - ((uint32_t)aux[(bits/8)-2] << 8) | - (uint32_t)aux[(bits/8)-1]; - crc2 = mode_s_checksum(aux, bits); + crc1 = ( (uint32_t)aux[(bits/8)-3] << 16) | + ((uint32_t)aux[(bits/8)-2] << 8) | + (uint32_t)aux[(bits/8)-1]; + crc2 = mode_s_checksum(aux, bits); - if (crc1 == crc2) { - // The error is fixed. Overwrite the original buffer with the - // corrected sequence, and returns the error bit position. - memcpy(msg, aux, bits/8); - // We return the two bits as a 16 bit integer by shifting 'i' - // on the left. This is possible since 'i' will always be - // non-zero because i starts from j+1. - return j | (i<<8); - } - } - } - return -1; + if (crc1 == crc2) + { + // The error is fixed. Overwrite the original buffer with the + // corrected sequence, and returns the error bit position. + memcpy(msg, aux, bits/8); + + // We return the two bits as a 16 bit integer by shifting 'i' + // on the left. This is possible since 'i' will always be + // non-zero because i starts from j+1. + return j | (i<<8); + } + } + } + return -1; } +// ========================================================================== // Hash the ICAO address to index our cache of MODE_S_ICAO_CACHE_LEN elements, // that is assumed to be a power of two. -uint32_t icao_cache_has_addr(uint32_t a) { - // The following three rounds wil make sure that every bit affects every - // output bit with ~ 50% of probability. - a = ((a >> 16) ^ a) * 0x45d9f3b; - a = ((a >> 16) ^ a) * 0x45d9f3b; - a = ((a >> 16) ^ a); - return a & (MODE_S_ICAO_CACHE_LEN-1); +uint32_t icao_cache_has_addr(uint32_t a) +{ + // The following three rounds wil make sure that every bit affects every + // output bit with ~ 50% of probability. + a = ((a >> 16) ^ a) * 0x45d9f3b; + a = ((a >> 16) ^ a) * 0x45d9f3b; + a = ((a >> 16) ^ a); + return a & (MODE_S_ICAO_CACHE_LEN-1); } +// ========================================================================== // Add the specified entry to the cache of recently seen ICAO addresses. Note // that we also add a timestamp so that we can make sure that the entry is only // valid for MODE_S_ICAO_CACHE_TTL seconds. -void add_recently_seen_icao_addr(mode_s_t *self, uint32_t addr) { - uint32_t h = icao_cache_has_addr(addr); - self->icao_cache[h*2] = addr; - self->icao_cache[h*2+1] = (uint32_t) time(NULL); +void add_recently_seen_icao_addr(mode_s_t *self, uint32_t addr) +{ + uint32_t h = icao_cache_has_addr(addr); + self->icao_cache[h*2] = addr; + self->icao_cache[h*2+1] = (uint32_t) time(NULL); } +// ========================================================================== // Returns 1 if the specified ICAO address was seen in a DF format with proper // checksum (not xored with address) no more than * MODE_S_ICAO_CACHE_TTL // seconds ago. Otherwise returns 0. -int icao_addr_was_recently_seen(mode_s_t *self, uint32_t addr) { - uint32_t h = icao_cache_has_addr(addr); - uint32_t a = self->icao_cache[h*2]; - int32_t t = self->icao_cache[h*2+1]; +int icao_addr_was_recently_seen(mode_s_t *self, uint32_t addr) +{ + uint32_t h = icao_cache_has_addr(addr); + uint32_t a = self->icao_cache[h*2]; + int32_t t = self->icao_cache[h*2+1]; - return a && a == addr && time(NULL)-t <= MODE_S_ICAO_CACHE_TTL; + return a && a == addr && time(NULL)-t <= MODE_S_ICAO_CACHE_TTL; } +// ========================================================================== // If the message type has the checksum xored with the ICAO address, try to // brute force it using a list of recently seen ICAO addresses. // @@ -230,285 +447,332 @@ int icao_addr_was_recently_seen(mode_s_t *self, uint32_t addr) { // // If the function successfully recovers a message with a correct checksum it // returns 1. Otherwise 0 is returned. -int brute_force_ap(mode_s_t *self, unsigned char *msg, struct mode_s_msg *mm) { - unsigned char aux[MODE_S_LONG_MSG_BYTES]; - int msgtype = mm->msgtype; - int msgbits = mm->msgbits; +int brute_force_ap(mode_s_t *self, unsigned char *msg, struct mode_s_msg *mm) +{ + unsigned char aux[MODE_S_LONG_MSG_BYTES]; + int msgtype = mm->msgtype; + int msgbits = mm->msgbits; - if (msgtype == 0 || // Short air surveillance - msgtype == 4 || // Surveillance, altitude reply - msgtype == 5 || // Surveillance, identity reply - msgtype == 16 || // Long Air-Air survillance - msgtype == 20 || // Comm-A, altitude request - msgtype == 21 || // Comm-A, identity request - msgtype == 24) // Comm-C ELM - { - uint32_t addr; - uint32_t crc; - int lastbyte = (msgbits/8)-1; + if (msgtype == 0 || // Short air surveillance + msgtype == 4 || // Surveillance, altitude reply + msgtype == 5 || // Surveillance, identity reply + msgtype == 16 || // Long Air-Air survillance + msgtype == 20 || // Comm-A, altitude request + msgtype == 21 || // Comm-A, identity request + msgtype == 24) // Comm-C ELM + { + uint32_t addr; + uint32_t crc; + int lastbyte = (msgbits/8)-1; - // Work on a copy. - memcpy(aux, msg, msgbits/8); + // Work on a copy. + memcpy(aux, msg, msgbits/8); - // Compute the CRC of the message and XOR it with the AP field so that - // we recover the address, because: - // - // (ADDR xor CRC) xor CRC = ADDR. - crc = mode_s_checksum(aux, msgbits); - aux[lastbyte] ^= crc & 0xff; - aux[lastbyte-1] ^= (crc >> 8) & 0xff; - aux[lastbyte-2] ^= (crc >> 16) & 0xff; - - // If the obtained address exists in our cache we consider the message - // valid. - addr = aux[lastbyte] | (aux[lastbyte-1] << 8) | (aux[lastbyte-2] << 16); - if (icao_addr_was_recently_seen(self, addr)) { - mm->aa1 = aux[lastbyte-2]; - mm->aa2 = aux[lastbyte-1]; - mm->aa3 = aux[lastbyte]; - return 1; - } - } - return 0; + // Compute the CRC of the message and XOR it with the AP field so that + // we recover the address, because: + // (ADDR xor CRC) xor CRC = ADDR. + crc = mode_s_checksum(aux, msgbits); + aux[lastbyte] ^= crc & 0xff; + aux[lastbyte-1] ^= (crc >> 8) & 0xff; + aux[lastbyte-2] ^= (crc >> 16) & 0xff; + + // If the obtained address exists in our cache we consider the message + // valid. + addr = aux[lastbyte] | (aux[lastbyte-1] << 8) | (aux[lastbyte-2] << 16); + + if (icao_addr_was_recently_seen(self, addr)) + { + mm->aa1 = aux[lastbyte-2]; + mm->aa2 = aux[lastbyte-1]; + mm->aa3 = aux[lastbyte]; + return 1; + } + } + return 0; } +// ========================================================================== // Decode the 13 bit AC altitude field (in DF 20 and others). Returns the // altitude, and set 'unit' to either MODE_S_UNIT_METERS or MDOES_UNIT_FEETS. -int decode_ac13_field(unsigned char *msg, int *unit) { - int m_bit = msg[3] & (1<<6); - int q_bit = msg[3] & (1<<4); +int decode_ac13_field(unsigned char *msg, int *unit) +{ + int m_bit = msg[3] & (1<<6); + int q_bit = msg[3] & (1<<4); - if (!m_bit) { - *unit = MODE_S_UNIT_FEET; - if (q_bit) { - // N is the 11 bit integer resulting from the removal of bit Q and M - int n = ((msg[2]&31)<<6) | - ((msg[3]&0x80)>>2) | - ((msg[3]&0x20)>>1) | - (msg[3]&15); - // The final altitude is due to the resulting number multiplied by - // 25, minus 1000. - return n*25-1000; - } else { - // TODO: Implement altitude where Q=0 and M=0 - } - } else { - *unit = MODE_S_UNIT_METERS; - // TODO: Implement altitude when meter unit is selected. - } - return 0; + if (!m_bit) + { + *unit = MODE_S_UNIT_FEET; + + if (q_bit) + { + // N is the 11 bit integer resulting from the removal of bit Q and M + int n = ((msg[2]&31)<<6) | + ((msg[3]&0x80)>>2) | + ((msg[3]&0x20)>>1) | + (msg[3]&15); + + // The final altitude is due to the resulting number multiplied by + // 25, minus 1000. + return n*25-1000; + } + else + { + // TODO: Implement altitude where Q=0 and M=0 + } + } + else + { + *unit = MODE_S_UNIT_METERS; + // TODO: Implement altitude when meter unit is selected. + } + return 0; } +// ========================================================================== // Decode the 12 bit AC altitude field (in DF 17 and others). Returns the // altitude or 0 if it can't be decoded. -int decode_ac12_field(unsigned char *msg, int *unit) { - int q_bit = msg[5] & 1; +int decode_ac12_field(unsigned char *msg, int *unit) +{ + int q_bit = msg[5] & 1; - if (q_bit) { - // N is the 11 bit integer resulting from the removal of bit Q - *unit = MODE_S_UNIT_FEET; - int n = ((msg[5]>>1)<<4) | ((msg[6]&0xF0) >> 4); - // The final altitude is due to the resulting number multiplied by 25, - // minus 1000. - return n*25-1000; - } else { - return 0; - } + if (q_bit) + { + // N is the 11 bit integer resulting from the removal of bit Q + *unit = MODE_S_UNIT_FEET; + int n = ((msg[5]>>1)<<4) | ((msg[6]&0xF0) >> 4); + + // The final altitude is due to the resulting number multiplied by 25, + // minus 1000. + return n*25-1000; + } + else + { + return 0; + } } -static const char *ais_charset = "?ABCDEFGHIJKLMNOPQRSTUVWXYZ????? ???????????????0123456789??????"; - +// ========================================================================== // Decode a raw Mode S message demodulated as a stream of bytes by // mode_s_detect(), and split it into fields populating a mode_s_msg structure. -void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg) { - uint32_t crc2; // Computed CRC, used to verify the message CRC. +static const char *ais_charset = "?ABCDEFGHIJKLMNOPQRSTUVWXYZ????? ???????????????0123456789??????"; - // Work on our local copy - memcpy(mm->msg, msg, MODE_S_LONG_MSG_BYTES); - msg = mm->msg; +void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg) +{ + uint32_t crc2; // Computed CRC, used to verify the message CRC. - // Get the message type ASAP as other operations depend on this - mm->msgtype = msg[0]>>3; // Downlink Format - mm->msgbits = mode_s_msg_len_by_type(mm->msgtype); + // Work on our local copy + memcpy(mm->msg, msg, MODE_S_LONG_MSG_BYTES); + msg = mm->msg; - // CRC is always the last three bytes. - mm->crc = ((uint32_t)msg[(mm->msgbits/8)-3] << 16) | - ((uint32_t)msg[(mm->msgbits/8)-2] << 8) | - (uint32_t)msg[(mm->msgbits/8)-1]; - crc2 = mode_s_checksum(msg, mm->msgbits); + // Get the message type ASAP as other operations depend on this + mm->msgtype = msg[0]>>3; // Downlink Format + mm->msgbits = mode_s_msg_len_by_type(mm->msgtype); - // Check CRC and fix single bit errors using the CRC when possible (DF 11 and 17). - mm->errorbit = -1; // No error - mm->crcok = (mm->crc == crc2); + // CRC is always the last three bytes. + mm->crc = ( (uint32_t)msg[(mm->msgbits/8)-3] << 16) | + ((uint32_t)msg[(mm->msgbits/8)-2] << 8) | + (uint32_t)msg[(mm->msgbits/8)-1]; + crc2 = mode_s_checksum(msg, mm->msgbits); - if (!mm->crcok && self->fix_errors && (mm->msgtype == 11 || mm->msgtype == 17)) { - if ((mm->errorbit = fix_single_bit_errors(msg, mm->msgbits)) != -1) { - mm->crc = mode_s_checksum(msg, mm->msgbits); - mm->crcok = 1; - } else if (self->aggressive && mm->msgtype == 17 && - (mm->errorbit = fix_two_bits_errors(msg, mm->msgbits)) != -1) { - mm->crc = mode_s_checksum(msg, mm->msgbits); - mm->crcok = 1; - } - } + // Check CRC and fix single bit errors using the CRC when possible (DF 11 and 17). + mm->errorbit = -1; // No error + mm->crcok = (mm->crc == crc2); - // Note that most of the other computation happens *after* we fix the - // single bit errors, otherwise we would need to recompute the fields - // again. - mm->ca = msg[0] & 7; // Responder capabilities. + if (!mm->crcok && self->fix_errors && (mm->msgtype == 11 || mm->msgtype == 17)) + { + if ((mm->errorbit = fix_single_bit_errors(msg, mm->msgbits)) != -1) + { + mm->crc = mode_s_checksum(msg, mm->msgbits); + mm->crcok = 1; + } + else if (self->aggressive && mm->msgtype == 17 && (mm->errorbit = fix_two_bits_errors(msg, mm->msgbits)) != -1) + { + mm->crc = mode_s_checksum(msg, mm->msgbits); + mm->crcok = 1; + } + } - // ICAO address - mm->aa1 = msg[1]; - mm->aa2 = msg[2]; - mm->aa3 = msg[3]; + // Note that most of the other computation happens *after* we fix the + // single bit errors, otherwise we would need to recompute the fields + // again. + mm->ca = msg[0] & 7; // Responder capabilities. - // DF 17 type (assuming this is a DF17, otherwise not used) - mm->metype = msg[4] >> 3; // Extended squitter message type. - mm->mesub = msg[4] & 7; // Extended squitter message subtype. + // ICAO address + mm->aa1 = msg[1]; + mm->aa2 = msg[2]; + mm->aa3 = msg[3]; - // Fields for DF4,5,20,21 - mm->fs = msg[0] & 7; // Flight status for DF4,5,20,21 - mm->dr = msg[1] >> 3 & 31; // Request extraction of downlink request. - mm->um = ((msg[1] & 7)<<3)| // Request extraction of downlink request. - msg[2]>>5; + // DF 17 type (assuming this is a DF17, otherwise not used) + mm->metype = msg[4] >> 3; // Extended squitter message type. + mm->mesub = msg[4] & 7; // Extended squitter message subtype. - // In the squawk (identity) field bits are interleaved like that (message - // bit 20 to bit 32): - // - // C1-A1-C2-A2-C4-A4-ZERO-B1-D1-B2-D2-B4-D4 - // - // So every group of three bits A, B, C, D represent an integer from 0 to - // 7. - // - // The actual meaning is just 4 octal numbers, but we convert it into a - // base ten number tha happens to represent the four octal numbers. - // - // For more info: http://en.wikipedia.org/wiki/Gillham_code - { - int a, b, c, d; + // Fields for DF4,5,20,21 + mm->fs = msg[0] & 7; // Flight status for DF4,5,20,21 + mm->dr = msg[1] >> 3 & 31; // Request extraction of downlink request. + mm->um = ( (msg[1] & 7)<<3) | msg[2]>>5;// Request extraction of downlink request. - a = ((msg[3] & 0x80) >> 5) | - ((msg[2] & 0x02) >> 0) | - ((msg[2] & 0x08) >> 3); - b = ((msg[3] & 0x02) << 1) | - ((msg[3] & 0x08) >> 2) | - ((msg[3] & 0x20) >> 5); - c = ((msg[2] & 0x01) << 2) | - ((msg[2] & 0x04) >> 1) | - ((msg[2] & 0x10) >> 4); - d = ((msg[3] & 0x01) << 2) | - ((msg[3] & 0x04) >> 1) | - ((msg[3] & 0x10) >> 4); - mm->identity = a*1000 + b*100 + c*10 + d; - } + // In the squawk (identity) field bits are interleaved like that (message + // bit 20 to bit 32): + // + // C1-A1-C2-A2-C4-A4-ZERO-B1-D1-B2-D2-B4-D4 + // + // So every group of three bits A, B, C, D represent an integer from 0 to + // 7. + // + // The actual meaning is just 4 octal numbers, but we convert it into a + // base ten number tha happens to represent the four octal numbers. + // + // For more info: http://en.wikipedia.org/wiki/Gillham_code + { + int a, b, c, d; - // DF 11 & 17: try to populate our ICAO addresses whitelist. DFs with an AP - // field (xored addr and crc), try to decode it. - if (mm->msgtype != 11 && mm->msgtype != 17) { - // Check if we can check the checksum for the Downlink Formats where - // the checksum is xored with the aircraft ICAO address. We try to - // brute force it using a list of recently seen aircraft addresses. - if (brute_force_ap(self, msg, mm)) { - // We recovered the message, mark the checksum as valid. - mm->crcok = 1; - } else { - mm->crcok = 0; - } - } else { - // If this is DF 11 or DF 17 and the checksum was ok, we can add this - // address to the list of recently seen addresses. - if (mm->crcok && mm->errorbit == -1) { - uint32_t addr = (mm->aa1 << 16) | (mm->aa2 << 8) | mm->aa3; - add_recently_seen_icao_addr(self, addr); - } - } + a = ((msg[3] & 0x80) >> 5) | + ((msg[2] & 0x02) >> 0) | + ((msg[2] & 0x08) >> 3); + b = ((msg[3] & 0x02) << 1) | + ((msg[3] & 0x08) >> 2) | + ((msg[3] & 0x20) >> 5); + c = ((msg[2] & 0x01) << 2) | + ((msg[2] & 0x04) >> 1) | + ((msg[2] & 0x10) >> 4); + d = ((msg[3] & 0x01) << 2) | + ((msg[3] & 0x04) >> 1) | + ((msg[3] & 0x10) >> 4); + mm->identity = a*1000 + b*100 + c*10 + d; + } - // Decode 13 bit altitude for DF0, DF4, DF16, DF20 - if (mm->msgtype == 0 || mm->msgtype == 4 || - mm->msgtype == 16 || mm->msgtype == 20) { - mm->altitude = decode_ac13_field(msg, &mm->unit); - } + // DF 11 & 17: try to populate our ICAO addresses whitelist. DFs with an AP + // field (xored addr and crc), try to decode it. + if (mm->msgtype != 11 && mm->msgtype != 17) + { + // Check if we can check the checksum for the Downlink Formats where + // the checksum is xored with the aircraft ICAO address. We try to + // brute force it using a list of recently seen aircraft addresses. + if (brute_force_ap(self, msg, mm)) + { + // We recovered the message, mark the checksum as valid. + mm->crcok = 1; + } + else + { + mm->crcok = 0; + } + } + else + { + // If this is DF 11 or DF 17 and the checksum was ok, we can add this + // address to the list of recently seen addresses. + if (mm->crcok && mm->errorbit == -1) + { + uint32_t addr = (mm->aa1 << 16) | (mm->aa2 << 8) | mm->aa3; + add_recently_seen_icao_addr(self, addr); + } + } - // Decode extended squitter specific stuff. - if (mm->msgtype == 17) { - // Decode the extended squitter message. + // Decode 13 bit altitude for DF0, DF4, DF16, DF20 + if (mm->msgtype == 0 || mm->msgtype == 4 || + mm->msgtype == 16 || mm->msgtype == 20) + { + mm->altitude = decode_ac13_field(msg, &mm->unit); + } - if (mm->metype >= 1 && mm->metype <= 4) { - // Aircraft Identification and Category - mm->aircraft_type = mm->metype-1; - mm->flight[0] = (ais_charset)[msg[5]>>2]; - mm->flight[1] = ais_charset[((msg[5]&3)<<4)|(msg[6]>>4)]; - mm->flight[2] = ais_charset[((msg[6]&15)<<2)|(msg[7]>>6)]; - mm->flight[3] = ais_charset[msg[7]&63]; - mm->flight[4] = ais_charset[msg[8]>>2]; - mm->flight[5] = ais_charset[((msg[8]&3)<<4)|(msg[9]>>4)]; - mm->flight[6] = ais_charset[((msg[9]&15)<<2)|(msg[10]>>6)]; - mm->flight[7] = ais_charset[msg[10]&63]; - mm->flight[8] = '\0'; - } else if (mm->metype >= 9 && mm->metype <= 18) { - // Airborne position Message - mm->fflag = msg[6] & (1<<2); - mm->tflag = msg[6] & (1<<3); - mm->altitude = decode_ac12_field(msg, &mm->unit); - mm->raw_latitude = ((msg[6] & 3) << 15) | - (msg[7] << 7) | - (msg[8] >> 1); - mm->raw_longitude = ((msg[8]&1) << 16) | - (msg[9] << 8) | - msg[10]; - } else if (mm->metype == 19 && mm->mesub >= 1 && mm->mesub <= 4) { - // Airborne Velocity Message - if (mm->mesub == 1 || mm->mesub == 2) { - mm->ew_dir = (msg[5]&4) >> 2; - mm->ew_velocity = ((msg[5]&3) << 8) | msg[6]; - mm->ns_dir = (msg[7]&0x80) >> 7; - mm->ns_velocity = ((msg[7]&0x7f) << 3) | ((msg[8]&0xe0) >> 5); - mm->vert_rate_source = (msg[8]&0x10) >> 4; - mm->vert_rate_sign = (msg[8]&0x8) >> 3; - mm->vert_rate = ((msg[8]&7) << 6) | ((msg[9]&0xfc) >> 2); - // Compute velocity and angle from the two speed components - mm->velocity = sqrt(mm->ns_velocity*mm->ns_velocity+ - mm->ew_velocity*mm->ew_velocity); - if (mm->velocity) { - int ewv = mm->ew_velocity; - int nsv = mm->ns_velocity; - double heading; + // Decode extended squitter specific stuff. + if (mm->msgtype == 17) + { + // Decode the extended squitter message. - if (mm->ew_dir) ewv *= -1; - if (mm->ns_dir) nsv *= -1; - heading = atan2(ewv, nsv); + if (mm->metype >= 1 && mm->metype <= 4) + { + // Aircraft Identification and Category + mm->aircraft_type = mm->metype-1; + mm->flight[0] = (ais_charset)[msg[5]>>2]; + mm->flight[1] = ais_charset[((msg[5]&3)<<4)|(msg[6]>>4)]; + mm->flight[2] = ais_charset[((msg[6]&15)<<2)|(msg[7]>>6)]; + mm->flight[3] = ais_charset[msg[7]&63]; + mm->flight[4] = ais_charset[msg[8]>>2]; + mm->flight[5] = ais_charset[((msg[8]&3)<<4)|(msg[9]>>4)]; + mm->flight[6] = ais_charset[((msg[9]&15)<<2)|(msg[10]>>6)]; + mm->flight[7] = ais_charset[msg[10]&63]; + mm->flight[8] = '\0'; + } + else if (mm->metype >= 9 && mm->metype <= 18) + { + // Airborne position Message + mm->fflag = msg[6] & (1<<2); + mm->tflag = msg[6] & (1<<3); + mm->altitude = decode_ac12_field(msg, &mm->unit); + mm->raw_latitude = ((msg[6] & 3) << 15) | + (msg[7] << 7) | + (msg[8] >> 1); + mm->raw_longitude = ((msg[8]&1) << 16) | + (msg[9] << 8) | + msg[10]; + } + else if (mm->metype == 19 && mm->mesub >= 1 && mm->mesub <= 4) + { + // Airborne Velocity Message + if (mm->mesub == 1 || mm->mesub == 2) + { + mm->ew_dir = (msg[5]&4) >> 2; + mm->ew_velocity = ((msg[5]&3) << 8) | msg[6]; + mm->ns_dir = (msg[7]&0x80) >> 7; + mm->ns_velocity = ((msg[7]&0x7f) << 3) | ((msg[8]&0xe0) >> 5); + mm->vert_rate_source = (msg[8]&0x10) >> 4; + mm->vert_rate_sign = (msg[8]&0x8) >> 3; + mm->vert_rate = ((msg[8]&7) << 6) | ((msg[9]&0xfc) >> 2); - // Convert to degrees. - mm->heading = heading * 360 / (M_PI*2); - // We don't want negative values but a 0-360 scale. - if (mm->heading < 0) mm->heading += 360; - } else { - mm->heading = 0; - } - } else if (mm->mesub == 3 || mm->mesub == 4) { - mm->heading_is_valid = msg[5] & (1<<2); - mm->heading = (360.0/128) * (((msg[5] & 3) << 5) | - (msg[6] >> 3)); - } - } - } - mm->phase_corrected = 0; // Set to 1 by the caller if needed. + // Compute velocity and angle from the two speed components + mm->velocity = sqrt(mm->ns_velocity*mm->ns_velocity+ + mm->ew_velocity*mm->ew_velocity); + + if (mm->velocity) + { + int ewv = mm->ew_velocity; + int nsv = mm->ns_velocity; + double heading; + + if (mm->ew_dir) ewv *= -1; + if (mm->ns_dir) nsv *= -1; + heading = atan2(ewv, nsv); + + // Convert to degrees. + mm->heading = heading * 360 / (M_PI*2); + + // We don't want negative values but a 0-360 scale. + if (mm->heading < 0) mm->heading += 360; + } + else + { + mm->heading = 0; + } + } + else if (mm->mesub == 3 || mm->mesub == 4) + { + mm->heading_is_valid = msg[5] & (1<<2); + mm->heading = (360.0/128) * (((msg[5] & 3) << 5) | (msg[6] >> 3)); + } + } + } + mm->phase_corrected = 0; // Set to 1 by the caller if needed. } +// ========================================================================== // Return -1 if the message is out of fase left-side // Return 1 if the message is out of fase right-size // Return 0 if the message is not particularly out of phase. // // Note: this function will access mag[-1], so the caller should make sure to // call it only if we are not at the start of the current buffer. -int detect_out_of_phase(uint16_t *mag) { - if (mag[3] > mag[2]/3) return 1; - if (mag[10] > mag[9]/3) return 1; - if (mag[6] > mag[7]/3) return -1; - if (mag[-1] > mag[1]/3) return -1; - return 0; +int detect_out_of_phase(uint16_t *mag) +{ + if (mag[3] > mag[2]/3) return 1; + if (mag[10] > mag[9]/3) return 1; + if (mag[6] > mag[7]/3) return -1; + if (mag[-1] > mag[1]/3) return -1; + return 0; } +// ========================================================================== // This function does not really correct the phase of the message, it just // applies a transformation to the first sample representing a given bit: // @@ -535,21 +799,27 @@ int detect_out_of_phase(uint16_t *mag) { // a zero, to detect another zero. Symmetrically if it is a one it will be more // likely to detect a one because of the transformation. In this way similar // levels will be interpreted more likely in the correct way. -void apply_phase_correction(uint16_t *mag) { - int j; +void apply_phase_correction(uint16_t *mag) +{ + int j; - mag += 16; // Skip preamble. - for (j = 0; j < (MODE_S_LONG_MSG_BITS-1)*2; j += 2) { - if (mag[j] > mag[j+1]) { - // One - mag[j+2] = (mag[j+2] * 5) / 4; - } else { - // Zero - mag[j+2] = (mag[j+2] * 4) / 5; - } - } + mag += 16; // Skip preamble. + for (j = 0; j < (MODE_S_LONG_MSG_BITS-1)*2; j += 2) + { + if (mag[j] > mag[j+1]) + { + // One + mag[j+2] = (mag[j+2] * 5) / 4; + } + else + { + // Zero + mag[j+2] = (mag[j+2] * 4) / 5; + } + } } +// ========================================================================== // Detect a Mode S messages inside the magnitude buffer pointed by 'mag' and of // size 'maglen' bytes. Every detected Mode S message is convert it into a // stream of bits and passed to the function to display it. @@ -584,87 +854,102 @@ void mode_s_detect(mode_s_t *self, uint16_t *mag, uint32_t maglen, mode_s_callba // 8 -- // 9 ------------------- - for (j = 0; j < maglen - MODE_S_FULL_LEN*2; j++) - { - int low, high, delta, i, errors; - int good_message = 0; + for (j = 0; j < maglen - MODE_S_FULL_LEN*2; j++) + { + int low, high, delta, i, errors; + int good_message = 0; - if (use_correction) goto good_preamble; // We already checked it. + // We already checked it - skip the preemble + if (!use_correction) + { + // First check of relations between the first 10 samples representing a + // valid preamble. We don't even investigate further if this simple + // test is not passed. + if (!( mag[j] > mag[j+1] && + mag[j+1] < mag[j+2] && + mag[j+2] > mag[j+3] && + mag[j+3] < mag[j] && + mag[j+4] < mag[j] && + mag[j+5] < mag[j] && + mag[j+6] < mag[j] && + mag[j+7] > mag[j+8] && + mag[j+8] < mag[j+9] && + mag[j+9] > mag[j+6])) + { + continue; + } - // First check of relations between the first 10 samples representing a - // valid preamble. We don't even investigate further if this simple - // test is not passed. - if (!(mag[j] > mag[j+1] && - mag[j+1] < mag[j+2] && - mag[j+2] > mag[j+3] && - mag[j+3] < mag[j] && - mag[j+4] < mag[j] && - mag[j+5] < mag[j] && - mag[j+6] < mag[j] && - mag[j+7] > mag[j+8] && - mag[j+8] < mag[j+9] && - mag[j+9] > mag[j+6])) - { - continue; - } + // The samples between the two spikes must be < than the average of the + // high spikes level. We don't test bits too near to the high levels as + // signals can be out of phase so part of the energy can be in the near + // samples. + high = (mag[j]+mag[j+2]+mag[j+7]+mag[j+9])/6; + if (mag[j+4] >= high || + mag[j+5] >= high) + { + continue; + } - // The samples between the two spikes must be < than the average of the - // high spikes level. We don't test bits too near to the high levels as - // signals can be out of phase so part of the energy can be in the near - // samples. - high = (mag[j]+mag[j+2]+mag[j+7]+mag[j+9])/6; - if (mag[j+4] >= high || - mag[j+5] >= high) - { - continue; - } + // Similarly samples in the range 11-14 must be low, as it is the space + // between the preamble and real data. Again we don't test bits too + // near to high levels, see above. + if (mag[j+11] >= high || + mag[j+12] >= high || + mag[j+13] >= high || + mag[j+14] >= high) + { + continue; + } + } - // Similarly samples in the range 11-14 must be low, as it is the space - // between the preamble and real data. Again we don't test bits too - // near to high levels, see above. - if (mag[j+11] >= high || - mag[j+12] >= high || - mag[j+13] >= high || - mag[j+14] >= high) - { - continue; - } + // If the previous attempt with this message failed, retry using + // magnitude correction. + if (use_correction) + { + memcpy(aux, mag+j+MODE_S_PREAMBLE_US*2, sizeof(aux)); + if (j && detect_out_of_phase(mag+j)) + { + apply_phase_correction(mag+j); + } + // TODO ... apply other kind of corrections. + } -good_preamble: - // If the previous attempt with this message failed, retry using - // magnitude correction. - if (use_correction) { - memcpy(aux, mag+j+MODE_S_PREAMBLE_US*2, sizeof(aux)); - if (j && detect_out_of_phase(mag+j)) { - apply_phase_correction(mag+j); - } - // TODO ... apply other kind of corrections. - } + // Decode all the next 112 bits, regardless of the actual message size. + // We'll check the actual message type later. + errors = 0; + for (i = 0; i < MODE_S_LONG_MSG_BITS*2; i += 2) + { + low = mag[j+i+MODE_S_PREAMBLE_US*2]; + high = mag[j+i+MODE_S_PREAMBLE_US*2+1]; + delta = low-high; - // Decode all the next 112 bits, regardless of the actual message size. - // We'll check the actual message type later. - errors = 0; - for (i = 0; i < MODE_S_LONG_MSG_BITS*2; i += 2) { - low = mag[j+i+MODE_S_PREAMBLE_US*2]; - high = mag[j+i+MODE_S_PREAMBLE_US*2+1]; - delta = low-high; - if (delta < 0) delta = -delta; + if (delta < 0) delta = -delta; - if (i > 0 && delta < 256) { - bits[i/2] = bits[i/2-1]; - } else if (low == high) { - // Checking if two adiacent samples have the same magnitude is - // an effective way to detect if it's just random noise that - // was detected as a valid preamble. - bits[i/2] = 2; // error - if (i < MODE_S_SHORT_MSG_BITS*2) errors++; - } else if (low > high) { - bits[i/2] = 1; - } else { - // (low < high) for exclusion - bits[i/2] = 0; - } - } + if (i > 0 && delta < 256) + { + bits[i/2] = bits[i/2-1]; + } + else if (low == high) + { + // Checking if two adiacent samples have the same magnitude is + // an effective way to detect if it's just random noise that + // was detected as a valid preamble. + bits[i/2] = 2; // error + if (i < MODE_S_SHORT_MSG_BITS*2) + { + errors++; + } + } + else if (low > high) + { + bits[i/2] = 1; + } + else + { + // (low < high) for exclusion + bits[i/2] = 0; + } + } // Restore the original message if we used magnitude correction. if (use_correction) @@ -745,4 +1030,4 @@ good_preamble: use_correction = 0; } } -} \ No newline at end of file +} diff --git a/examples/cpp/modes.h b/examples/cpp/modes.h index aae8303..2d2f3e1 100644 --- a/examples/cpp/modes.h +++ b/examples/cpp/modes.h @@ -1,4 +1,5 @@ /* + * Modified source file by David Michaeli @ CaribouLabs Ltd. Apr. 2022 * Source of file: https://github.com/watson/libmodes * Author: Thomas Watson (@watson) * Contact: w@tson.dk / https://twitter.com/wa7son @@ -16,7 +17,7 @@ extern "C" { #include #include #include -#include +#include #define MODE_S_ICAO_CACHE_LEN 1024 // Power of two required #define MODE_S_LONG_MSG_BYTES (112/8) @@ -26,8 +27,8 @@ extern "C" { // Program state typedef struct { - // Internal state - uint32_t icao_cache[sizeof(uint32_t)*MODE_S_ICAO_CACHE_LEN*2]; // Recently seen ICAO addresses cache + // Internal state - recently seen ICAO addresses cache + uint32_t icao_cache[sizeof(uint32_t)*MODE_S_ICAO_CACHE_LEN*2]; // Configuration int fix_errors; // Single bit error correction if true @@ -38,7 +39,7 @@ typedef struct // The struct we use to store information about a decoded message struct mode_s_msg { - // Generic fields + // ------ Generic fields ------------ unsigned char msg[MODE_S_LONG_MSG_BYTES]; // Binary message int msgbits; // Number of bits in message int msgtype; // Downlink format # @@ -48,10 +49,10 @@ struct mode_s_msg int aa1, aa2, aa3; // ICAO Address bytes 1 2 and 3 int phase_corrected; // True if phase correction was applied. - // DF 11 + // ------ DF 11 --------------------- int ca; // Responder capabilities. - // DF 17 + // ------ DF 17 --------------------- int metype; // Extended squitter message type. int mesub; // Extended squitter message subtype. int heading_is_valid; @@ -71,7 +72,7 @@ struct mode_s_msg int vert_rate; // Vertical rate. int velocity; // Computed from EW and NS velocity. - // DF4, DF5, DF20, DF21 + // ------ DF4, DF5, DF20, DF21 ------- int fs; // Flight status for DF4,5,20,21 int dr; // Request extraction of downlink request. int um; // Request extraction of downlink request. @@ -86,6 +87,7 @@ typedef void (*mode_s_callback_t)(mode_s_t *self, struct mode_s_msg *mm); void mode_s_init(mode_s_t *self); void mode_s_detect(mode_s_t *self, uint16_t *mag, uint32_t maglen, mode_s_callback_t); void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg); +void mode_s_display_message(struct mode_s_msg *mm); #ifdef __cplusplus }