|
|
@ -26,6 +26,7 @@ |
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
#include <math.h> |
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32 |
|
|
|
#ifndef _WIN32 |
|
|
|
#include <unistd.h> |
|
|
|
#include <unistd.h> |
|
|
@ -44,8 +45,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
|
#define sleep Sleep |
|
|
|
#define sleep Sleep |
|
|
|
#undef min |
|
|
|
|
|
|
|
#undef max |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#define ADSB_RATE 2000000 |
|
|
|
#define ADSB_RATE 2000000 |
|
|
@ -59,6 +58,9 @@ static sem_t data_ready; |
|
|
|
static volatile int do_exit = 0; |
|
|
|
static volatile int do_exit = 0; |
|
|
|
static rtlsdr_dev_t *dev = NULL; |
|
|
|
static rtlsdr_dev_t *dev = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* look up table, could be made smaller */ |
|
|
|
|
|
|
|
uint8_t pyth[129][129]; |
|
|
|
|
|
|
|
|
|
|
|
/* todo, bundle these up in a struct */ |
|
|
|
/* todo, bundle these up in a struct */ |
|
|
|
uint8_t *buffer; |
|
|
|
uint8_t *buffer; |
|
|
|
int verbose_output = 0; |
|
|
|
int verbose_output = 0; |
|
|
@ -88,6 +90,8 @@ void usage(void) |
|
|
|
"Streaming with netcat:\n" |
|
|
|
"Streaming with netcat:\n" |
|
|
|
"\trtl_adsb | netcat -lp 8080\n" |
|
|
|
"\trtl_adsb | netcat -lp 8080\n" |
|
|
|
"\twhile true; do rtl_adsb | nc -lp 8080; done\n" |
|
|
|
"\twhile true; do rtl_adsb | nc -lp 8080; done\n" |
|
|
|
|
|
|
|
"Streaming with socat:\n" |
|
|
|
|
|
|
|
"\trtl_adsb | socat -u - TCP4:sdrsharp.com:47806\n" |
|
|
|
"\n"); |
|
|
|
"\n"); |
|
|
|
exit(1); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} |
|
|
@ -136,20 +140,34 @@ void display(int *frame, int len) |
|
|
|
fprintf(file, "--------------\n"); |
|
|
|
fprintf(file, "--------------\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int magnitute(unsigned char *buf, int len) |
|
|
|
void pyth_precompute(void) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int x, y; |
|
|
|
|
|
|
|
for (x=0; x<129; x++) { |
|
|
|
|
|
|
|
for (y=0; y<129; y++) { |
|
|
|
|
|
|
|
pyth[x][y] = (uint8_t)round(sqrt(x*x + y*y)); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline uint8_t abs8(uint8_t x) |
|
|
|
|
|
|
|
/* do not subtract 128 from the raw iq, this handles it */ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (x >= 128) { |
|
|
|
|
|
|
|
return x - 128;} |
|
|
|
|
|
|
|
return 128 - x; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int magnitute(uint8_t *buf, int len) |
|
|
|
/* takes i/q, changes buf in place, returns new len */ |
|
|
|
/* takes i/q, changes buf in place, returns new len */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i, mag; |
|
|
|
int i; |
|
|
|
for (i=0; i<len; i+=2) { |
|
|
|
for (i=0; i<len; i+=2) { |
|
|
|
mag = abs((int)buf[i]-128) + abs((int)buf[i+1]-128); |
|
|
|
buf[i/2] = pyth[abs8(buf[i])][abs8(buf[i+1])]; |
|
|
|
if (mag > 255) { // todo, compression
|
|
|
|
|
|
|
|
mag = 255;} |
|
|
|
|
|
|
|
buf[i/2] = (unsigned char)mag; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return len/2; |
|
|
|
return len/2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
inline unsigned char single_manchester(unsigned char a, unsigned char b, unsigned char c, unsigned char d) |
|
|
|
inline uint8_t single_manchester(uint8_t a, uint8_t b, uint8_t c, uint8_t d) |
|
|
|
/* takes 4 consecutive real samples, return 0 or 1, 255 on error */ |
|
|
|
/* takes 4 consecutive real samples, return 0 or 1, 255 on error */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
int bit, bit_p; |
|
|
|
int bit, bit_p; |
|
|
@ -190,33 +208,33 @@ inline unsigned char single_manchester(unsigned char a, unsigned char b, unsigne |
|
|
|
return 255; |
|
|
|
return 255; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
inline unsigned char min(unsigned char a, unsigned char b) |
|
|
|
inline uint8_t min8(uint8_t a, uint8_t b) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return a<b ? a : b; |
|
|
|
return a<b ? a : b; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
inline unsigned char max(unsigned char a, unsigned char b) |
|
|
|
inline uint8_t max8(uint8_t a, uint8_t b) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return a>b ? a : b; |
|
|
|
return a>b ? a : b; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
inline int preamble(unsigned char *buf, int len, int i) |
|
|
|
inline int preamble(uint8_t *buf, int len, int i) |
|
|
|
/* returns 0/1 for preamble at index i */ |
|
|
|
/* returns 0/1 for preamble at index i */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i2; |
|
|
|
int i2; |
|
|
|
unsigned char low = 0; |
|
|
|
uint8_t low = 0; |
|
|
|
unsigned char high = 255; |
|
|
|
uint8_t high = 255; |
|
|
|
for (i2=0; i2<preamble_len; i2++) { |
|
|
|
for (i2=0; i2<preamble_len; i2++) { |
|
|
|
switch (i2) { |
|
|
|
switch (i2) { |
|
|
|
case 0: |
|
|
|
case 0: |
|
|
|
case 2: |
|
|
|
case 2: |
|
|
|
case 7: |
|
|
|
case 7: |
|
|
|
case 9: |
|
|
|
case 9: |
|
|
|
//high = min(high, buf[i+i2]);
|
|
|
|
//high = min8(high, buf[i+i2]);
|
|
|
|
high = buf[i+i2]; |
|
|
|
high = buf[i+i2]; |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
//low = max(low, buf[i+i2]);
|
|
|
|
//low = max8(low, buf[i+i2]);
|
|
|
|
low = buf[i+i2]; |
|
|
|
low = buf[i+i2]; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -226,12 +244,12 @@ inline int preamble(unsigned char *buf, int len, int i) |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void manchester(unsigned char *buf, int len) |
|
|
|
void manchester(uint8_t *buf, int len) |
|
|
|
/* overwrites magnitude buffer with valid bits (255 on errors) */ |
|
|
|
/* overwrites magnitude buffer with valid bits (255 on errors) */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
/* a and b hold old values to verify local manchester */ |
|
|
|
/* a and b hold old values to verify local manchester */ |
|
|
|
unsigned char a=0, b=0; |
|
|
|
uint8_t a=0, b=0; |
|
|
|
unsigned char bit; |
|
|
|
uint8_t bit; |
|
|
|
int i, i2, start, errors; |
|
|
|
int i, i2, start, errors; |
|
|
|
// todo, allow wrap across buffers
|
|
|
|
// todo, allow wrap across buffers
|
|
|
|
i = 0; |
|
|
|
i = 0; |
|
|
@ -272,7 +290,7 @@ void manchester(unsigned char *buf, int len) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void messages(unsigned char *buf, int len) |
|
|
|
void messages(uint8_t *buf, int len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i, i2, start, preamble_found; |
|
|
|
int i, i2, start, preamble_found; |
|
|
|
int data_i, index, shift, frame_len; |
|
|
|
int data_i, index, shift, frame_len; |
|
|
@ -288,7 +306,7 @@ void messages(unsigned char *buf, int len) |
|
|
|
if (buf[i]) { |
|
|
|
if (buf[i]) { |
|
|
|
index = data_i / 8; |
|
|
|
index = data_i / 8; |
|
|
|
shift = 7 - (data_i % 8); |
|
|
|
shift = 7 - (data_i % 8); |
|
|
|
adsb_frame[index] |= (unsigned char)(1<<shift); |
|
|
|
adsb_frame[index] |= (uint8_t)(1<<shift); |
|
|
|
} |
|
|
|
} |
|
|
|
if (data_i == 7) { |
|
|
|
if (data_i == 7) { |
|
|
|
if (adsb_frame[0] == 0) { |
|
|
|
if (adsb_frame[0] == 0) { |
|
|
@ -343,6 +361,7 @@ int main(int argc, char **argv) |
|
|
|
int ppm_error = 0; |
|
|
|
int ppm_error = 0; |
|
|
|
char vendor[256], product[256], serial[256]; |
|
|
|
char vendor[256], product[256], serial[256]; |
|
|
|
sem_init(&data_ready, 0, 0); |
|
|
|
sem_init(&data_ready, 0, 0); |
|
|
|
|
|
|
|
pyth_precompute(); |
|
|
|
|
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1) |
|
|
|
while ((opt = getopt(argc, argv, "d:g:p:e:Q:VS")) != -1) |
|
|
|
{ |
|
|
|
{ |
|
|
|