removed threading holdovers from dump1090. started working on android build (not working yet). map drawing now resumes next frame if frame times out

Former-commit-id: 4271671e19b70a7333649bb93bff920d1fa1acd0
Former-commit-id: 9c5d89f2af4f235ccb5cd7b983443d63907ba6ad
This commit is contained in:
nathan 2020-02-18 15:37:41 -08:00
parent ed853a3145
commit 8c281d95e5
23 changed files with 161 additions and 2675 deletions

39
Android.mk Normal file
View file

@ -0,0 +1,39 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main.out
SDL_PATH := ~/Downloads/SDL
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/$(SDL_PATH)/include \
$(LOCAL_PATH)/$(SDL_PATH)
#LOCALCFLAGS=
LOCAL_SRC_FILES := \
$(SDL_PATH)/src/main/android/SDL_android_main.cpp \
allstates.c \
input.c \
mapdata.c \
monokai.c \
planeObj.c \
anet.c \
font.c \
interactive.c \
mode_ac.c \
net_io.c \
status.c \
draw.c \
init.c \
list.c \
mode_s.c \
parula.c \
view1090.c
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_gfx SDL2_ttf
LOCAL_LDLIBS := -lGLESv1_CM #-lstdc++
include $(BUILD_EXECUTABLE)

3
Application.mk Normal file
View file

@ -0,0 +1,3 @@
APP_ABI := arm64-v8a
APP_PLATFORM := android-29
APP_BUILD_SCRIPT := Android.mk

View file

@ -2,7 +2,7 @@
# When building a package or installing otherwise in the system, make
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
#
PROGNAME=dump1090
PROGNAME=view1090
ifdef PREFIX
BINDIR=$(PREFIX)/bin
@ -10,8 +10,8 @@ SHAREDIR=$(PREFIX)/share/$(PROGNAME)
EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\"
endif
CFLAGS=-O2 -g -Wall -W `pkg-config --cflags librtlsdr`
LIBS=`pkg-config --libs librtlsdr` -lpthread -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
CFLAGS=-O2 -g -Wall -W
LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
CC=gcc
all: view1090

42
draw.c
View file

@ -343,6 +343,9 @@ void drawTrail(double *oldDx, double *oldDy, double *oldHeading, time_t * oldSee
//tick marks
age = 1.0 - (double) 4.0 * (now - oldSeen[currentIdx]) / TRAIL_TTL;
colorVal = (uint8_t)floor(255.0 * age);
double vec[3];
vec[0] = sin(oldHeading[currentIdx] * M_PI / 180);
vec[1] = -cos(oldHeading[currentIdx] * M_PI / 180);
@ -427,6 +430,19 @@ void drawPolys(QuadTree *tree, double screen_lat_min, double screen_lat_max, dou
return;
}
if(appData.mapContinue && appData.mapContinue != tree) {
return;
}
if(appData.mapContinue && appData.mapContinue == tree) {
appData.mapContinue = NULL;
}
if(mstime() - appData.lastFrameTime > FRAMETIME) {
appData.mapContinue = tree;
return;
}
if (tree->lat_min > screen_lat_max || screen_lat_min > tree->lat_max) {
return;
}
@ -438,8 +454,14 @@ void drawPolys(QuadTree *tree, double screen_lat_min, double screen_lat_max, dou
drawPolys(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
drawPolys(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
drawPolys(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
//if we didn't make it to the last child then need to set mapContinue to this node to make sure all children get drawn next time
if(appData.mapContinue) {
appData.mapContinue = tree;
}
drawPolys(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
double dx, dy;
// if(!(tree->lat_min > screen_lat_min &&
// tree->lat_max < screen_lat_max &&
@ -581,7 +603,11 @@ void drawGeography() {
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, appData.screen_height * -0.2);
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, appData.screen_width, appData.screen_height * 1.2);
drawPolys(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
if(appData.mapContinue) {
drawPolys(appData.mapContinue, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
} else {
drawPolys(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
}
}
void drawSignalMarks(struct planeObj *p, int x, int y) {
@ -935,7 +961,7 @@ void drawPlanes() {
drawTrail(p->oldLon, p->oldLat, p->oldHeading, p->oldSeen, p->oldIdx);
}
if(selectedPlane == NULL) {
if(selectedPlane == NULL && appData.touchx && appData.touchy) {
if((p->cx - appData.touchx) * (p->cx - appData.touchx) + (p->cy - appData.touchy) * (p->cy - appData.touchy) < 900) {
if(selection) {
if((p->cx - appData.touchx) * (p->cx - appData.touchx) + (p->cy - appData.touchy) * (p->cy - appData.touchy) <
@ -1089,12 +1115,16 @@ void draw() {
updateStatus();
if(appData.mapMoved) {
if(appData.mapMoved || appData.mapContinue) {
SDL_SetRenderTarget(appData.renderer, appData.mapTexture);
SDL_SetRenderDrawColor(appData.renderer, 0, 0, 0, 0);
SDL_RenderClear(appData.renderer);
if(appData.mapContinue == NULL) {
SDL_SetRenderDrawColor(appData.renderer, 0, 0, 0, 0);
SDL_RenderClear(appData.renderer);
}
drawGeography();
drawScaleBars();
SDL_SetRenderTarget(appData.renderer, NULL );

View file

@ -1 +1 @@
f1227086156bca68b563a45527bb1442279dc1f5
4019e6c1da59af5e54909b8625f116916ed7b2de

View file

@ -1,904 +0,0 @@
// dump1090, a Mode S messages decoder for RTLSDR devices.
//
// Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>
//
// 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 "coaa.h"
#include "dump1090.h"
//
// ============================= Utility functions ==========================
//
void sigintHandler(int dummy) {
MODES_NOTUSED(dummy);
signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety
Modes.exit = 1; // Signal to threads that we are done
}
//
// =============================== Terminal handling ========================
//
#ifndef _WIN32
// Get the number of rows after the terminal changes size.
int getTermRows() {
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
return (w.ws_row);
}
// Handle resizing terminal
void sigWinchCallback() {
signal(SIGWINCH, SIG_IGN);
Modes.interactive_rows = getTermRows();
interactiveShowData();
signal(SIGWINCH, sigWinchCallback);
}
#else
int getTermRows() { return MODES_INTERACTIVE_ROWS;}
#endif
//
// =============================== Initialization ===========================
//
void modesInitConfig(void) {
// Default everything to zero/NULL
memset(&Modes, 0, sizeof(Modes));
// Now initialise things that should not be 0/NULL to their defaults
Modes.gain = MODES_MAX_GAIN;
Modes.freq = MODES_DEFAULT_FREQ;
Modes.ppm_error = MODES_DEFAULT_PPM;
Modes.check_crc = 1;
Modes.net_heartbeat_rate = MODES_NET_HEARTBEAT_RATE;
Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT;
Modes.net_output_raw_port = MODES_NET_OUTPUT_RAW_PORT;
Modes.net_input_raw_port = MODES_NET_INPUT_RAW_PORT;
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT;
Modes.net_http_port = MODES_NET_HTTP_PORT;
Modes.interactive_rows = getTermRows();
Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.fUserLat = MODES_USER_LATITUDE_DFLT;
Modes.fUserLon = MODES_USER_LONGITUDE_DFLT;
}
//
//=========================================================================
//
void modesInit(void) {
int i, q;
pthread_mutex_init(&Modes.pDF_mutex,NULL);
pthread_mutex_init(&Modes.data_mutex,NULL);
pthread_cond_init(&Modes.data_cond,NULL);
// Allocate the various buffers used by Modes
if ( ((Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2) ) == NULL) ||
((Modes.pFileData = (uint16_t *) malloc(MODES_ASYNC_BUF_SIZE) ) == NULL) ||
((Modes.magnitude = (uint16_t *) malloc(MODES_ASYNC_BUF_SIZE+MODES_PREAMBLE_SIZE+MODES_LONG_MSG_SIZE) ) == NULL) ||
((Modes.maglut = (uint16_t *) malloc(sizeof(uint16_t) * 256 * 256) ) == NULL) ||
((Modes.beastOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) ||
((Modes.rawOut = (char *) malloc(MODES_RAWOUT_BUF_SIZE) ) == NULL) )
{
fprintf(stderr, "Out of memory allocating data buffer.\n");
exit(1);
}
// Clear the buffers that have just been allocated, just in-case
memset(Modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2);
memset(Modes.pFileData,127, MODES_ASYNC_BUF_SIZE);
memset(Modes.magnitude, 0, MODES_ASYNC_BUF_SIZE+MODES_PREAMBLE_SIZE+MODES_LONG_MSG_SIZE);
// Validate the users Lat/Lon home location inputs
if ( (Modes.fUserLat > 90.0) // Latitude must be -90 to +90
|| (Modes.fUserLat < -90.0) // and
|| (Modes.fUserLon > 360.0) // Longitude must be -180 to +360
|| (Modes.fUserLon < -180.0) ) {
Modes.fUserLat = Modes.fUserLon = 0.0;
} else if (Modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0
Modes.fUserLon -= 360.0;
}
// If both Lat and Lon are 0.0 then the users location is either invalid/not-set, or (s)he's in the
// Atlantic ocean off the west coast of Africa. This is unlikely to be correct.
// Set the user LatLon valid flag only if either Lat or Lon are non zero. Note the Greenwich meridian
// is at 0.0 Lon,so we must check for either fLat or fLon being non zero not both.
// Testing the flag at runtime will be much quicker than ((fLon != 0.0) || (fLat != 0.0))
Modes.bUserFlags &= ~MODES_USER_LATLON_VALID;
if ((Modes.fUserLat != 0.0) || (Modes.fUserLon != 0.0)) {
Modes.bUserFlags |= MODES_USER_LATLON_VALID;
}
// Limit the maximum requested raw output size to less than one Ethernet Block
if (Modes.net_output_raw_size > (MODES_RAWOUT_BUF_FLUSH))
{Modes.net_output_raw_size = MODES_RAWOUT_BUF_FLUSH;}
if (Modes.net_output_raw_rate > (MODES_RAWOUT_BUF_RATE))
{Modes.net_output_raw_rate = MODES_RAWOUT_BUF_RATE;}
if (Modes.net_sndbuf_size > (MODES_NET_SNDBUF_MAX))
{Modes.net_sndbuf_size = MODES_NET_SNDBUF_MAX;}
// Initialise the Block Timers to something half sensible
ftime(&Modes.stSystemTimeBlk);
for (i = 0; i < MODES_ASYNC_BUF_NUMBER; i++)
{Modes.stSystemTimeRTL[i] = Modes.stSystemTimeBlk;}
// Each I and Q value varies from 0 to 255, which represents a range from -1 to +1. To get from the
// unsigned (0-255) range you therefore subtract 127 (or 128 or 127.5) from each I and Q, giving you
// a range from -127 to +128 (or -128 to +127, or -127.5 to +127.5)..
//
// To decode the AM signal, you need the magnitude of the waveform, which is given by sqrt((I^2)+(Q^2))
// The most this could be is if I&Q are both 128 (or 127 or 127.5), so you could end up with a magnitude
// of 181.019 (or 179.605, or 180.312)
//
// However, in reality the magnitude of the signal should never exceed the range -1 to +1, because the
// values are I = rCos(w) and Q = rSin(w). Therefore the integer computed magnitude should (can?) never
// exceed 128 (or 127, or 127.5 or whatever)
//
// If we scale up the results so that they range from 0 to 65535 (16 bits) then we need to multiply
// by 511.99, (or 516.02 or 514). antirez's original code multiplies by 360, presumably because he's
// assuming the maximim calculated amplitude is 181.019, and (181.019 * 360) = 65166.
//
// So lets see if we can improve things by subtracting 127.5, Well in integer arithmatic we can't
// subtract half, so, we'll double everything up and subtract one, and then compensate for the doubling
// in the multiplier at the end.
//
// If we do this we can never have I or Q equal to 0 - they can only be as small as +/- 1.
// This gives us a minimum magnitude of root 2 (0.707), so the dynamic range becomes (1.414-255). This
// also affects our scaling value, which is now 65535/(255 - 1.414), or 258.433254
//
// The sums then become mag = 258.433254 * (sqrt((I*2-255)^2 + (Q*2-255)^2) - 1.414)
// or mag = (258.433254 * sqrt((I*2-255)^2 + (Q*2-255)^2)) - 365.4798
//
// We also need to clip mag just incaes any rogue I/Q values somehow do have a magnitude greater than 255.
//
for (i = 0; i <= 255; i++) {
for (q = 0; q <= 255; q++) {
int mag, mag_i, mag_q;
mag_i = (i * 2) - 255;
mag_q = (q * 2) - 255;
mag = (int) round((sqrt((mag_i*mag_i)+(mag_q*mag_q)) * 258.433254) - 365.4798);
Modes.maglut[(i*256)+q] = (uint16_t) ((mag < 65535) ? mag : 65535);
}
}
// Prepare error correction tables
modesInitErrorInfo();
}
//
// =============================== RTLSDR handling ==========================
//
void modesInitRTLSDR(void) {
int j;
int device_count;
char vendor[256], product[256], serial[256];
device_count = rtlsdr_get_device_count();
if (!device_count) {
fprintf(stderr, "No supported RTLSDR devices found.\n");
exit(1);
}
fprintf(stderr, "Found %d device(s):\n", device_count);
for (j = 0; j < device_count; j++) {
rtlsdr_get_device_usb_strings(j, vendor, product, serial);
fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial,
(j == Modes.dev_index) ? "(currently selected)" : "");
}
if (rtlsdr_open(&Modes.dev, Modes.dev_index) < 0) {
fprintf(stderr, "Error opening the RTLSDR device: %s\n",
strerror(errno));
exit(1);
}
// Set gain, frequency, sample rate, and reset the device
rtlsdr_set_tuner_gain_mode(Modes.dev,
(Modes.gain == MODES_AUTO_GAIN) ? 0 : 1);
if (Modes.gain != MODES_AUTO_GAIN) {
if (Modes.gain == MODES_MAX_GAIN) {
// Find the maximum gain available
int numgains;
int gains[100];
numgains = rtlsdr_get_tuner_gains(Modes.dev, gains);
Modes.gain = gains[numgains-1];
fprintf(stderr, "Max available gain is: %.2f\n", Modes.gain/10.0);
}
rtlsdr_set_tuner_gain(Modes.dev, Modes.gain);
fprintf(stderr, "Setting gain to: %.2f\n", Modes.gain/10.0);
} else {
fprintf(stderr, "Using automatic gain control.\n");
}
rtlsdr_set_freq_correction(Modes.dev, Modes.ppm_error);
if (Modes.enable_agc) rtlsdr_set_agc_mode(Modes.dev, 1);
rtlsdr_set_center_freq(Modes.dev, Modes.freq);
rtlsdr_set_sample_rate(Modes.dev, MODES_DEFAULT_RATE);
rtlsdr_reset_buffer(Modes.dev);
fprintf(stderr, "Gain reported by device: %.2f\n",
rtlsdr_get_tuner_gain(Modes.dev)/10.0);
}
//
//=========================================================================
//
// We use a thread reading data in background, while the main thread
// handles decoding and visualization of data to the user.
//
// The reading thread calls the RTLSDR API to read data asynchronously, and
// uses a callback to populate the data buffer.
//
// A Mutex is used to avoid races with the decoding thread.
//
void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) {
MODES_NOTUSED(ctx);
// Lock the data buffer variables before accessing them
pthread_mutex_lock(&Modes.data_mutex);
Modes.iDataIn &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase!!!
// Get the system time for this block
ftime(&Modes.stSystemTimeRTL[Modes.iDataIn]);
if (len > MODES_ASYNC_BUF_SIZE) {len = MODES_ASYNC_BUF_SIZE;}
// Queue the new data
Modes.pData[Modes.iDataIn] = (uint16_t *) buf;
Modes.iDataIn = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn + 1);
Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut);
if (Modes.iDataReady == 0) {
// Ooooops. We've just received the MODES_ASYNC_BUF_NUMBER'th outstanding buffer
// This means that RTLSDR is currently overwriting the MODES_ASYNC_BUF_NUMBER+1
// buffer, but we havent yet processed it, so we're going to lose it. There
// isn't much we can do to recover the lost data, but we can correct things to
// avoid any additional problems.
Modes.iDataOut = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataOut+1);
Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1);
Modes.iDataLost++;
}
// Signal to the other thread that new data is ready, and unlock
pthread_cond_signal(&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
}
//
//=========================================================================
//
// This is used when --ifile is specified in order to read data from file
// instead of using an RTLSDR device
//
void readDataFromFile(void) {
pthread_mutex_lock(&Modes.data_mutex);
while(Modes.exit == 0) {
ssize_t nread, toread;
unsigned char *p;
if (Modes.iDataReady) {
pthread_cond_wait(&Modes.data_cond, &Modes.data_mutex);
continue;
}
if (Modes.interactive) {
// When --ifile and --interactive are used together, slow down
// playing at the natural rate of the RTLSDR received.
pthread_mutex_unlock(&Modes.data_mutex);
usleep(64000);
pthread_mutex_lock(&Modes.data_mutex);
}
toread = MODES_ASYNC_BUF_SIZE;
p = (unsigned char *) Modes.pFileData;
while(toread) {
nread = read(Modes.fd, p, toread);
if (nread <= 0) {
Modes.exit = 1; // Signal the other threads to exit.
break;
}
p += nread;
toread -= nread;
}
if (toread) {
// Not enough data on file to fill the buffer? Pad with no signal.
memset(p,127,toread);
}
Modes.iDataIn &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase!!!
// Get the system time for this block
ftime(&Modes.stSystemTimeRTL[Modes.iDataIn]);
// Queue the new data
Modes.pData[Modes.iDataIn] = Modes.pFileData;
Modes.iDataIn = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn + 1);
Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut);
// Signal to the other thread that new data is ready
pthread_cond_signal(&Modes.data_cond);
}
}
//
//=========================================================================
//
// We read data using a thread, so the main thread only handles decoding
// without caring about data acquisition
//
void *readerThreadEntryPoint(void *arg) {
MODES_NOTUSED(arg);
if (Modes.filename == NULL) {
rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL,
MODES_ASYNC_BUF_NUMBER,
MODES_ASYNC_BUF_SIZE);
} else {
readDataFromFile();
}
// Signal to the other thread that new data is ready - dummy really so threads don't mutually lock
pthread_cond_signal(&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
#ifndef _WIN32
pthread_exit(NULL);
#else
return NULL;
#endif
}
//
// ============================== Snip mode =================================
//
// Get raw IQ samples and filter everything is < than the specified level
// for more than 256 samples in order to reduce example file size
//
void snipMode(int level) {
int i, q;
uint64_t c = 0;
while ((i = getchar()) != EOF && (q = getchar()) != EOF) {
if (abs(i-127) < level && abs(q-127) < level) {
c++;
if (c > MODES_PREAMBLE_SIZE) continue;
} else {
c = 0;
}
putchar(i);
putchar(q);
}
}
//
// ================================ Main ====================================
//
void showHelp(void) {
printf(
"-----------------------------------------------------------------------------\n"
"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n"
"-----------------------------------------------------------------------------\n"
"--device-index <index> Select RTL device (default: 0)\n"
"--gain <db> Set gain (default: max gain. Use -10 for auto-gain)\n"
"--enable-agc Enable the Automatic Gain Control (default: off)\n"
"--freq <hz> Set frequency (default: 1090 Mhz)\n"
"--ifile <filename> Read data from file (use '-' for stdin)\n"
"--interactive Interactive mode refreshing data on screen\n"
"--interactive-rows <num> Max number of rows in interactive mode (default: 15)\n"
"--interactive-ttl <sec> Remove from list if idle for <sec> (default: 60)\n"
"--interactive-rtl1090 Display flight table in RTL1090 format\n"
"--raw Show only messages hex values\n"
"--net Enable networking\n"
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
"--net-beast TCP raw output in Beast binary format\n"
"--net-only Enable just networking, no RTL device or file used\n"
"--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n"
"--net-http-port <port> HTTP server port (default: 8080)\n"
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
"--net-sbs-port <port> TCP BaseStation output listen port (default: 30003)\n"
"--net-bi-port <port> TCP Beast input listen port (default: 30004)\n"
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
"--net-ro-size <size> TCP raw output minimum size (default: 0)\n"
"--net-ro-rate <rate> TCP raw output memory flush rate (default: 0)\n"
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
"--net-buffer <n> TCP buffer size 64Kb * (2^n) (default: n=0, 64Kb)\n"
"--lat <latitude> Reference/receiver latitude for surface posn (opt)\n"
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
"--fix Enable single-bits error correction using CRC\n"
"--no-fix Disable single-bits error correction using CRC\n"
"--no-crc-check Disable messages with broken CRC (discouraged)\n"
"--phase-enhance Enable phase enhancement\n"
"--aggressive More CPU for more messages (two bits fixes, ...)\n"
"--mlat display raw messages in Beast ascii mode\n"
"--stats With --ifile print stats at exit. No other output\n"
"--stats-every <seconds> Show and reset stats every <seconds> seconds\n"
"--onlyaddr Show only ICAO addresses (testing purposes)\n"
"--metric Use metric units (meters, km/h, ...)\n"
"--snip <level> Strip IQ file removing samples < level\n"
"--debug <flags> Debug mode (verbose), see README for details\n"
"--quiet Disable output to stdout. Use for daemon applications\n"
"--ppm <error> Set receiver error in parts per million (default 0)\n"
"--help Show this help\n"
"\n"
"Debug mode flags: d = Log frames decoded with errors\n"
" D = Log frames decoded with zero errors\n"
" c = Log frames with bad CRC\n"
" C = Log frames with good CRC\n"
" p = Log frames with bad preamble\n"
" n = Log network debugging info\n"
" j = Log frames to frames.js, loadable by debug.html\n"
);
}
#ifdef _WIN32
void showCopyright(void) {
uint64_t llTime = time(NULL) + 1;
printf(
"-----------------------------------------------------------------------------\n"
"| dump1090 ModeS Receiver Ver : " MODES_DUMP1090_VERSION " |\n"
"-----------------------------------------------------------------------------\n"
"\n"
" Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>\n"
" Copyright (C) 2014 by Malcolm Robb <support@attavionics.com>\n"
"\n"
" All rights reserved.\n"
"\n"
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
" ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
"\n"
" For further details refer to <https://github.com/MalcolmRobb/dump1090>\n"
"\n"
);
// delay for 1 second to give the user a chance to read the copyright
while (llTime >= time(NULL)) {}
}
#endif
static void display_stats(void) {
int j;
time_t now = time(NULL);
printf("\n\n");
if (Modes.interactive)
interactiveShowData();
printf("Statistics as at %s", ctime(&now));
printf("%d sample blocks processed\n", Modes.stat_blocks_processed);
printf("%d sample blocks dropped\n", Modes.stat_blocks_dropped);
printf("%d ModeA/C detected\n", Modes.stat_ModeAC);
printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble);
printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Len_Corrected);
printf("%d DF-?? fields corrected for type\n", Modes.stat_DF_Type_Corrected);
printf("%d demodulated with 0 errors\n", Modes.stat_demodulated0);
printf("%d demodulated with 1 error\n", Modes.stat_demodulated1);
printf("%d demodulated with 2 errors\n", Modes.stat_demodulated2);
printf("%d demodulated with > 2 errors\n", Modes.stat_demodulated3);
printf("%d with good crc\n", Modes.stat_goodcrc);
printf("%d with bad crc\n", Modes.stat_badcrc);
printf("%d errors corrected\n", Modes.stat_fixed);
for (j = 0; j < MODES_MAX_BITERRORS; j++) {
printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors");
}
if (Modes.phase_enhance) {
printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase);
printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0);
printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1);
printf("%d phase enhanced demodulated with 2 errors\n", Modes.stat_ph_demodulated2);
printf("%d phase enhanced demodulated with > 2 errors\n", Modes.stat_ph_demodulated3);
printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc);
printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc);
printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed);
for (j = 0; j < MODES_MAX_BITERRORS; j++) {
printf(" %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors");
}
}
printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed);
fflush(stdout);
Modes.stat_blocks_processed =
Modes.stat_blocks_dropped = 0;
Modes.stat_ModeAC =
Modes.stat_valid_preamble =
Modes.stat_DF_Len_Corrected =
Modes.stat_DF_Type_Corrected =
Modes.stat_demodulated0 =
Modes.stat_demodulated1 =
Modes.stat_demodulated2 =
Modes.stat_demodulated3 =
Modes.stat_goodcrc =
Modes.stat_badcrc =
Modes.stat_fixed = 0;
Modes.stat_out_of_phase =
Modes.stat_ph_demodulated0 =
Modes.stat_ph_demodulated1 =
Modes.stat_ph_demodulated2 =
Modes.stat_ph_demodulated3 =
Modes.stat_ph_goodcrc =
Modes.stat_ph_badcrc =
Modes.stat_ph_fixed = 0;
for (j = 0; j < MODES_MAX_BITERRORS; j++) {
Modes.stat_ph_bit_fix[j] = 0;
Modes.stat_bit_fix[j] = 0;
}
}
//
//=========================================================================
//
// This function is called a few times every second by main in order to
// perform tasks we need to do continuously, like accepting new clients
// from the net, refreshing the screen in interactive mode, and so forth
//
void backgroundTasks(void) {
static time_t next_stats;
if (Modes.net) {
modesReadFromClients();
}
// If Modes.aircrafts is not NULL, remove any stale aircraft
if (Modes.aircrafts) {
interactiveRemoveStaleAircrafts();
}
// Refresh screen when in interactive mode
if (Modes.interactive) {
interactiveShowData();
}
if (Modes.stats > 0) {
time_t now = time(NULL);
if (now > next_stats) {
if (next_stats != 0)
display_stats();
next_stats = now + Modes.stats;
}
}
}
//
//=========================================================================
//
int verbose_device_search(char *s)
{
int i, device_count, device, offset;
char *s2;
char vendor[256], product[256], serial[256];
device_count = rtlsdr_get_device_count();
if (!device_count) {
fprintf(stderr, "No supported devices found.\n");
return -1;
}
fprintf(stderr, "Found %d device(s):\n", device_count);
for (i = 0; i < device_count; i++) {
rtlsdr_get_device_usb_strings(i, vendor, product, serial);
fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial);
}
fprintf(stderr, "\n");
/* does string look like raw id number */
device = (int)strtol(s, &s2, 0);
if (s2[0] == '\0' && device >= 0 && device < device_count) {
fprintf(stderr, "Using device %d: %s\n",
device, rtlsdr_get_device_name((uint32_t)device));
return device;
}
/* does string exact match a serial */
for (i = 0; i < device_count; i++) {
rtlsdr_get_device_usb_strings(i, vendor, product, serial);
if (strcmp(s, serial) != 0) {
continue;}
device = i;
fprintf(stderr, "Using device %d: %s\n",
device, rtlsdr_get_device_name((uint32_t)device));
return device;
}
/* does string prefix match a serial */
for (i = 0; i < device_count; i++) {
rtlsdr_get_device_usb_strings(i, vendor, product, serial);
if (strncmp(s, serial, strlen(s)) != 0) {
continue;}
device = i;
fprintf(stderr, "Using device %d: %s\n",
device, rtlsdr_get_device_name((uint32_t)device));
return device;
}
/* does string suffix match a serial */
for (i = 0; i < device_count; i++) {
rtlsdr_get_device_usb_strings(i, vendor, product, serial);
offset = strlen(serial) - strlen(s);
if (offset < 0) {
continue;}
if (strncmp(s, serial+offset, strlen(s)) != 0) {
continue;}
device = i;
fprintf(stderr, "Using device %d: %s\n",
device, rtlsdr_get_device_name((uint32_t)device));
return device;
}
fprintf(stderr, "No matching devices found.\n");
return -1;
}
//
//=========================================================================
//
int main(int argc, char **argv) {
int j;
// Set sane defaults
modesInitConfig();
signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program)
// Parse the command line options
for (j = 1; j < argc; j++) {
int more = j+1 < argc; // There are more arguments
if (!strcmp(argv[j],"--device-index") && more) {
Modes.dev_index = verbose_device_search(argv[++j]);
} else if (!strcmp(argv[j],"--gain") && more) {
Modes.gain = (int) (atof(argv[++j])*10); // Gain is in tens of DBs
} else if (!strcmp(argv[j],"--enable-agc")) {
Modes.enable_agc++;
} else if (!strcmp(argv[j],"--freq") && more) {
Modes.freq = (int) strtoll(argv[++j],NULL,10);
} else if (!strcmp(argv[j],"--ifile") && more) {
Modes.filename = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--fix")) {
Modes.nfix_crc = 1;
} else if (!strcmp(argv[j],"--no-fix")) {
Modes.nfix_crc = 0;
} else if (!strcmp(argv[j],"--no-crc-check")) {
Modes.check_crc = 0;
} else if (!strcmp(argv[j],"--phase-enhance")) {
Modes.phase_enhance = 1;
} else if (!strcmp(argv[j],"--raw")) {
Modes.raw = 1;
} else if (!strcmp(argv[j],"--net")) {
Modes.net = 1;
} else if (!strcmp(argv[j],"--modeac")) {
Modes.mode_ac = 1;
} else if (!strcmp(argv[j],"--net-beast")) {
Modes.beast = 1;
} else if (!strcmp(argv[j],"--net-only")) {
Modes.net = 1;
Modes.net_only = 1;
} else if (!strcmp(argv[j],"--net-heartbeat") && more) {
Modes.net_heartbeat_rate = atoi(argv[++j]) * 15;
} else if (!strcmp(argv[j],"--net-ro-size") && more) {
Modes.net_output_raw_size = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-ro-rate") && more) {
Modes.net_output_raw_rate = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-ro-port") && more) {
if (Modes.beast) // Required for legacy backward compatibility
{Modes.net_output_beast_port = atoi(argv[++j]);;}
else
{Modes.net_output_raw_port = atoi(argv[++j]);}
} else if (!strcmp(argv[j],"--net-ri-port") && more) {
Modes.net_input_raw_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bo-port") && more) {
Modes.net_output_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
Modes.net_input_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bind-address") && more) {
Modes.net_bind_address = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) {
Modes.net_http_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
Modes.net_output_sbs_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-buffer") && more) {
Modes.net_sndbuf_size = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--onlyaddr")) {
Modes.onlyaddr = 1;
} else if (!strcmp(argv[j],"--metric")) {
Modes.metric = 1;
} else if (!strcmp(argv[j],"--aggressive")) {
Modes.nfix_crc = MODES_MAX_BITERRORS;
} else if (!strcmp(argv[j],"--interactive")) {
Modes.interactive = 1;
} else if (!strcmp(argv[j],"--interactive-rows") && more) {
Modes.interactive_rows = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--interactive-ttl") && more) {
Modes.interactive_display_ttl = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--lat") && more) {
Modes.fUserLat = atof(argv[++j]);
} else if (!strcmp(argv[j],"--lon") && more) {
Modes.fUserLon = atof(argv[++j]);
} else if (!strcmp(argv[j],"--debug") && more) {
char *f = argv[++j];
while(*f) {
switch(*f) {
case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break;
case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break;
case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break;
case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break;
case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break;
case 'n': Modes.debug |= MODES_DEBUG_NET; break;
case 'j': Modes.debug |= MODES_DEBUG_JS; break;
default:
fprintf(stderr, "Unknown debugging flag: %c\n", *f);
exit(1);
break;
}
f++;
}
} else if (!strcmp(argv[j],"--stats")) {
Modes.stats = -1;
} else if (!strcmp(argv[j],"--stats-every") && more) {
Modes.stats = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--snip") && more) {
snipMode(atoi(argv[++j]));
exit(0);
} else if (!strcmp(argv[j],"--help")) {
showHelp();
exit(0);
} else if (!strcmp(argv[j],"--ppm") && more) {
Modes.ppm_error = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--quiet")) {
Modes.quiet = 1;
} else if (!strcmp(argv[j],"--mlat")) {
Modes.mlat = 1;
} else if (!strcmp(argv[j],"--interactive-rtl1090")) {
Modes.interactive = 1;
Modes.interactive_rtl1090 = 1;
} else {
fprintf(stderr,
"Unknown or not enough arguments for option '%s'.\n\n",
argv[j]);
showHelp();
exit(1);
}
}
#ifdef _WIN32
// Try to comply with the Copyright license conditions for binary distribution
if (!Modes.quiet) {showCopyright();}
#endif
#ifndef _WIN32
// Setup for SIGWINCH for handling lines
if (Modes.interactive) {signal(SIGWINCH, sigWinchCallback);}
#endif
// Initialization
modesInit();
if (Modes.net_only) {
fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
} else if (Modes.filename == NULL) {
modesInitRTLSDR();
} else {
if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
Modes.fd = STDIN_FILENO;
} else if ((Modes.fd = open(Modes.filename,
#ifdef _WIN32
(O_RDONLY | O_BINARY)
#else
(O_RDONLY)
#endif
)) == -1) {
perror("Opening data file");
exit(1);
}
}
if (Modes.net) modesInitNet();
// If the user specifies --net-only, just run in order to serve network
// clients without reading data from the RTL device
while (Modes.net_only) {
if (Modes.exit) exit(0); // If we exit net_only nothing further in main()
backgroundTasks();
usleep(100000);
}
// Create the thread that will read the data from the device.
pthread_create(&Modes.reader_thread, NULL, readerThreadEntryPoint, NULL);
pthread_mutex_lock(&Modes.data_mutex);
while (Modes.exit == 0) {
if (Modes.iDataReady == 0) {
pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex); // This unlocks Modes.data_mutex, and waits for Modes.data_cond
continue; // Once (Modes.data_cond) occurs, it locks Modes.data_mutex
}
// Modes.data_mutex is Locked, and (Modes.iDataReady != 0)
if (Modes.iDataReady) { // Check we have new data, just in case!!
Modes.iDataOut &= (MODES_ASYNC_BUF_NUMBER-1); // Just incase
// Translate the next lot of I/Q samples into Modes.magnitude
computeMagnitudeVector(Modes.pData[Modes.iDataOut]);
Modes.stSystemTimeBlk = Modes.stSystemTimeRTL[Modes.iDataOut];
// Update the input buffer pointer queue
Modes.iDataOut = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataOut + 1);
Modes.iDataReady = (MODES_ASYNC_BUF_NUMBER-1) & (Modes.iDataIn - Modes.iDataOut);
// If we lost some blocks, correct the timestamp
if (Modes.iDataLost) {
Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES * 6 * Modes.iDataLost);
Modes.stat_blocks_dropped += Modes.iDataLost;
Modes.iDataLost = 0;
}
// It's safe to release the lock now
pthread_cond_signal (&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
// Process data after releasing the lock, so that the capturing
// thread can read data while we perform computationally expensive
// stuff at the same time.
detectModeS(Modes.magnitude, MODES_ASYNC_BUF_SAMPLES);
// Update the timestamp ready for the next block
Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES*6);
Modes.stat_blocks_processed++;
} else {
pthread_cond_signal (&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
}
backgroundTasks();
pthread_mutex_lock(&Modes.data_mutex);
}
// If --stats were given, print statistics
if (Modes.stats) {
display_stats();
}
if (Modes.filename == NULL) {
rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly
rtlsdr_close(Modes.dev);
}
pthread_cond_destroy(&Modes.data_cond); // Thread cleanup
pthread_mutex_destroy(&Modes.data_mutex);
pthread_join(Modes.reader_thread,NULL); // Wait on reader thread exit
#ifndef _WIN32
pthread_exit(0);
#else
return (0);
#endif
}
//
//=========================================================================
//

BIN
font.o

Binary file not shown.

2
init.c
View file

@ -43,6 +43,8 @@ void init(char *title) {
appData.screen_width, appData.screen_height);
appData.mapMoved = 1;
selectedPlane = NULL;
appData.mapContinue = NULL;
if(appData.fullscreen) {
//\SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // make the scaled rendering look smoother.

BIN
init.o

Binary file not shown.

View file

@ -1 +1 @@
d4947b5d39abcf0073465f4b5683173294132874
e65446c295519dac23cf6b702c274d4cfb873e7f

View file

@ -60,15 +60,20 @@ void interactiveCreateDF(struct aircraft *a, struct modesMessage *mm) {
pDF->pAircraft = a;
memcpy(pDF->msg, mm->msg, MODES_LONG_MSG_BYTES);
if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
if ((pDF->pNext = Modes.pDF)) {
Modes.pDF->pPrev = pDF;
}
Modes.pDF = pDF;
pthread_mutex_unlock(&Modes.pDF_mutex);
} else {
free(pDF);
// if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
// if ((pDF->pNext = Modes.pDF)) {
// Modes.pDF->pPrev = pDF;
// }
// Modes.pDF = pDF;
// pthread_mutex_unlock(&Modes.pDF_mutex);
// } else {
// free(pDF);
// }
if ((pDF->pNext = Modes.pDF)) {
Modes.pDF->pPrev = pDF;
}
Modes.pDF = pDF;
}
}
//
@ -81,45 +86,75 @@ void interactiveRemoveStaleDF(time_t now) {
// Only fiddle with the DF list if we gain possession of the mutex
// If we fail to get the mutex we'll get another chance to tidy the
// DF list in a second or so.
if (!pthread_mutex_trylock(&Modes.pDF_mutex)) {
pDF = Modes.pDF;
while(pDF) {
if ((now - pDF->seen) > Modes.interactive_delete_ttl) {
if (Modes.pDF == pDF) {
Modes.pDF = NULL;
} else {
prev->pNext = NULL;
}
// if (!pthread_mutex_trylock(&Modes.pDF_mutex)) {
// pDF = Modes.pDF;
// while(pDF) {
// if ((now - pDF->seen) > Modes.interactive_delete_ttl) {
// if (Modes.pDF == pDF) {
// Modes.pDF = NULL;
// } else {
// prev->pNext = NULL;
// }
// All DF's in the list from here onwards will be time
// expired, so delete them all
while (pDF) {
prev = pDF; pDF = pDF->pNext;
free(prev);
}
// // All DF's in the list from here onwards will be time
// // expired, so delete them all
// while (pDF) {
// prev = pDF; pDF = pDF->pNext;
// free(prev);
// }
// } else {
// prev = pDF; pDF = pDF->pNext;
// }
// }
// pthread_mutex_unlock (&Modes.pDF_mutex);
// }
pDF = Modes.pDF;
while(pDF) {
if ((now - pDF->seen) > Modes.interactive_delete_ttl) {
if (Modes.pDF == pDF) {
Modes.pDF = NULL;
} else {
prev = pDF; pDF = pDF->pNext;
prev->pNext = NULL;
}
// All DF's in the list from here onwards will be time
// expired, so delete them all
while (pDF) {
prev = pDF; pDF = pDF->pNext;
free(prev);
}
} else {
prev = pDF; pDF = pDF->pNext;
}
pthread_mutex_unlock (&Modes.pDF_mutex);
}
}
struct stDF *interactiveFindDF(uint32_t addr) {
struct stDF *pDF = NULL;
if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
pDF = Modes.pDF;
while(pDF) {
if (pDF->addr == addr) {
pthread_mutex_unlock (&Modes.pDF_mutex);
return (pDF);
}
pDF = pDF->pNext;
// if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
// pDF = Modes.pDF;
// while(pDF) {
// if (pDF->addr == addr) {
// pthread_mutex_unlock (&Modes.pDF_mutex);
// return (pDF);
// }
// pDF = pDF->pNext;
// }
// pthread_mutex_unlock (&Modes.pDF_mutex);
// }
pDF = Modes.pDF;
while(pDF) {
if (pDF->addr == addr) {
return (pDF);
}
pthread_mutex_unlock (&Modes.pDF_mutex);
pDF = pDF->pNext;
}
return (NULL);
}
//

Binary file not shown.

BIN
list.o

Binary file not shown.

BIN
monokai.o

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,183 +0,0 @@
/*
* Module: sched.h
*
* Purpose:
* Provides an implementation of POSIX realtime extensions
* as defined in
*
* POSIX 1003.1b-1993 (POSIX.1b)
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.au
*
* The current list of contributors is contained
* in the file CONTRIBUTORS included with the source
* code distribution. The list can also be seen at the
* following World Wide Web location:
* http://sources.redhat.com/pthreads-win32/contributors.html
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library in the file COPYING.LIB;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(_SCHED_H)
#define _SCHED_H
#undef PTW32_SCHED_LEVEL
#if defined(_POSIX_SOURCE)
#define PTW32_SCHED_LEVEL 0
/* Early POSIX */
#endif
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
#undef PTW32_SCHED_LEVEL
#define PTW32_SCHED_LEVEL 1
/* Include 1b, 1c and 1d */
#endif
#if defined(INCLUDE_NP)
#undef PTW32_SCHED_LEVEL
#define PTW32_SCHED_LEVEL 2
/* Include Non-Portable extensions */
#endif
#define PTW32_SCHED_LEVEL_MAX 3
#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL)
#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX
/* Include everything */
#endif
#if defined(__GNUC__) && !defined(__declspec)
# error Please upgrade your GNU compiler to one that supports __declspec.
#endif
/*
* When building the library, you should define PTW32_BUILD so that
* the variables/functions are exported correctly. When using the library,
* do NOT define PTW32_BUILD, and then the variables/functions will
* be imported correctly.
*/
#if !defined(PTW32_STATIC_LIB)
# if defined(PTW32_BUILD)
# define PTW32_DLLPORT __declspec (dllexport)
# else
# define PTW32_DLLPORT __declspec (dllimport)
# endif
#else
# define PTW32_DLLPORT
#endif
/*
* This is a duplicate of what is in the autoconf config.h,
* which is only used when building the pthread-win32 libraries.
*/
#if !defined(PTW32_CONFIG_H)
# if defined(WINCE)
# define NEED_ERRNO
# define NEED_SEM
# endif
# if defined(__MINGW64__)
# define HAVE_STRUCT_TIMESPEC
# define HAVE_MODE_T
# elif defined(_UWIN) || defined(__MINGW32__)
# define HAVE_MODE_T
# endif
#endif
/*
*
*/
#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
#if defined(NEED_ERRNO)
#include "need_errno.h"
#else
#include <errno.h>
#endif
#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */
#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN)
# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
/* For pid_t */
# include <sys/types.h>
/* Required by Unix 98 */
# include <time.h>
# else
typedef int pid_t;
# endif
#else
typedef int pid_t;
#endif
/* Thread scheduling policies */
enum {
SCHED_OTHER = 0,
SCHED_FIFO,
SCHED_RR,
SCHED_MIN = SCHED_OTHER,
SCHED_MAX = SCHED_RR
};
struct sched_param {
int sched_priority;
};
#if defined(__cplusplus)
extern "C"
{
#endif /* __cplusplus */
PTW32_DLLPORT int __cdecl sched_yield (void);
PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy);
PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy);
PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
/*
* Note that this macro returns ENOTSUP rather than
* ENOSYS as might be expected. However, returning ENOSYS
* should mean that sched_get_priority_{min,max} are
* not implemented as well as sched_rr_get_interval.
* This is not the case, since we just don't support
* round-robin scheduling. Therefore I have chosen to
* return the same value as sched_setscheduler when
* SCHED_RR is passed to it.
*/
#define sched_rr_get_interval(_pid, _interval) \
( errno = ENOTSUP, (int) -1 )
#if defined(__cplusplus)
} /* End of extern "C" */
#endif /* __cplusplus */
#undef PTW32_SCHED_LEVEL
#undef PTW32_SCHED_LEVEL_MAX
#endif /* !_SCHED_H */

View file

@ -1,169 +0,0 @@
/*
* Module: semaphore.h
*
* Purpose:
* Semaphores aren't actually part of the PThreads standard.
* They are defined by the POSIX Standard:
*
* POSIX 1003.1b-1993 (POSIX.1b)
*
* --------------------------------------------------------------------------
*
* Pthreads-win32 - POSIX Threads Library for Win32
* Copyright(C) 1998 John E. Bossom
* Copyright(C) 1999,2005 Pthreads-win32 contributors
*
* Contact Email: rpj@callisto.canberra.edu.au
*
* The current list of contributors is contained
* in the file CONTRIBUTORS included with the source
* code distribution. The list can also be seen at the
* following World Wide Web location:
* http://sources.redhat.com/pthreads-win32/contributors.html
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library in the file COPYING.LIB;
* if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined( SEMAPHORE_H )
#define SEMAPHORE_H
#undef PTW32_SEMAPHORE_LEVEL
#if defined(_POSIX_SOURCE)
#define PTW32_SEMAPHORE_LEVEL 0
/* Early POSIX */
#endif
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
#undef PTW32_SEMAPHORE_LEVEL
#define PTW32_SEMAPHORE_LEVEL 1
/* Include 1b, 1c and 1d */
#endif
#if defined(INCLUDE_NP)
#undef PTW32_SEMAPHORE_LEVEL
#define PTW32_SEMAPHORE_LEVEL 2
/* Include Non-Portable extensions */
#endif
#define PTW32_SEMAPHORE_LEVEL_MAX 3
#if !defined(PTW32_SEMAPHORE_LEVEL)
#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX
/* Include everything */
#endif
#if defined(__GNUC__) && ! defined (__declspec)
# error Please upgrade your GNU compiler to one that supports __declspec.
#endif
/*
* When building the library, you should define PTW32_BUILD so that
* the variables/functions are exported correctly. When using the library,
* do NOT define PTW32_BUILD, and then the variables/functions will
* be imported correctly.
*/
#if !defined(PTW32_STATIC_LIB)
# if defined(PTW32_BUILD)
# define PTW32_DLLPORT __declspec (dllexport)
# else
# define PTW32_DLLPORT __declspec (dllimport)
# endif
#else
# define PTW32_DLLPORT
#endif
/*
* This is a duplicate of what is in the autoconf config.h,
* which is only used when building the pthread-win32 libraries.
*/
#if !defined(PTW32_CONFIG_H)
# if defined(WINCE)
# define NEED_ERRNO
# define NEED_SEM
# endif
# if defined(__MINGW64__)
# define HAVE_STRUCT_TIMESPEC
# define HAVE_MODE_T
# elif defined(_UWIN) || defined(__MINGW32__)
# define HAVE_MODE_T
# endif
#endif
/*
*
*/
#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX
#if defined(NEED_ERRNO)
#include "need_errno.h"
#else
#include <errno.h>
#endif
#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */
#define _POSIX_SEMAPHORES
#if defined(__cplusplus)
extern "C"
{
#endif /* __cplusplus */
#if !defined(HAVE_MODE_T)
typedef unsigned int mode_t;
#endif
typedef struct sem_t_ * sem_t;
PTW32_DLLPORT int __cdecl sem_init (sem_t * sem,
int pshared,
unsigned int value);
PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem);
PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem);
PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem);
PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem,
const struct timespec * abstime);
PTW32_DLLPORT int __cdecl sem_post (sem_t * sem);
PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem,
int count);
PTW32_DLLPORT int __cdecl sem_open (const char * name,
int oflag,
mode_t mode,
unsigned int value);
PTW32_DLLPORT int __cdecl sem_close (sem_t * sem);
PTW32_DLLPORT int __cdecl sem_unlink (const char * name);
PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem,
int * sval);
#if defined(__cplusplus)
} /* End of extern "C" */
#endif /* __cplusplus */
#undef PTW32_SEMAPHORE_LEVEL
#undef PTW32_SEMAPHORE_LEVEL_MAX
#endif /* !SEMAPHORE_H */

View file

@ -1 +1 @@
9aa844df5159c2a246895c0eb2a306f53d0a36fd
00319fecb996b4196487ff551c1c4fcd04063dcc

View file

@ -44,6 +44,7 @@ typedef struct AppData
int touchy;
int mapMoved;
QuadTree *mapContinue;
uint64_t lastFrameTime;
} AppData;

View file

@ -1 +1 @@
cbbacac08ce30232fcad4a508249c7e61768effa
c71ae5a169099a989da238f49c409fb014f13fd2

View file

@ -89,9 +89,9 @@ void view1090InitConfig(void) {
//
void view1090Init(void) {
pthread_mutex_init(&Modes.pDF_mutex,NULL);
pthread_mutex_init(&Modes.data_mutex,NULL);
pthread_cond_init(&Modes.data_cond,NULL);
// pthread_mutex_init(&Modes.pDF_mutex,NULL);
// pthread_mutex_init(&Modes.data_mutex,NULL);
// pthread_cond_init(&Modes.data_cond,NULL);
#ifdef _WIN32
if ( (!Modes.wsaData.wVersion)

View file

@ -1 +1 @@
790297577270307a97648484360f0eeb3de83233
71f6442ad1518278cce9fee8235924b9bbe56cc6