kopia lustrzana https://github.com/cyoung/stratux
Formatting.
rodzic
229df30ff4
commit
a8e8562e5f
|
@ -36,7 +36,8 @@ static void read_from_stdin(void);
|
||||||
static int process_buffer(uint16_t *phi, int len, uint64_t offset);
|
static int process_buffer(uint16_t *phi, int len, uint64_t offset);
|
||||||
static int demod_adsb_frame(uint16_t *phi, uint8_t *to, int *rs_errors);
|
static int demod_adsb_frame(uint16_t *phi, uint8_t *to, int *rs_errors);
|
||||||
static int demod_uplink_frame(uint16_t *phi, uint8_t *to, int *rs_errors);
|
static int demod_uplink_frame(uint16_t *phi, uint8_t *to, int *rs_errors);
|
||||||
static void demod_frame(uint16_t *phi, uint8_t *frame, int bytes, int16_t center_dphi);
|
static void demod_frame(uint16_t *phi, uint8_t *frame, int bytes,
|
||||||
|
int16_t center_dphi);
|
||||||
static void handle_adsb_frame(uint64_t timestamp, uint8_t *frame, int rs);
|
static void handle_adsb_frame(uint64_t timestamp, uint8_t *frame, int rs);
|
||||||
static void handle_uplink_frame(uint64_t timestamp, uint8_t *frame, int rs);
|
static void handle_uplink_frame(uint64_t timestamp, uint8_t *frame, int rs);
|
||||||
|
|
||||||
|
@ -49,8 +50,7 @@ static void handle_uplink_frame(uint64_t timestamp, uint8_t *frame, int rs);
|
||||||
#ifdef USE_SIGNED_OVERFLOW
|
#ifdef USE_SIGNED_OVERFLOW
|
||||||
#define phi_difference(from, to) ((int16_t)((to) - (from)))
|
#define phi_difference(from, to) ((int16_t)((to) - (from)))
|
||||||
#else
|
#else
|
||||||
inline int16_t phi_difference(uint16_t from, uint16_t to)
|
inline int16_t phi_difference(uint16_t from, uint16_t to) {
|
||||||
{
|
|
||||||
int32_t difference = to - from; // lies in the range -65535 .. +65535
|
int32_t difference = to - from; // lies in the range -65535 .. +65535
|
||||||
if (difference >= 32768) // +32768..+65535
|
if (difference >= 32768) // +32768..+65535
|
||||||
return difference - 65536; // -> -32768..-1: always in range
|
return difference - 65536; // -> -32768..-1: always in range
|
||||||
|
@ -62,8 +62,7 @@ inline int16_t phi_difference(uint16_t from, uint16_t to)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BUILD_LIB
|
#ifndef BUILD_LIB
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
make_atan2_table();
|
make_atan2_table();
|
||||||
init_fec();
|
init_fec();
|
||||||
read_from_stdin();
|
read_from_stdin();
|
||||||
|
@ -71,16 +70,15 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static CallBack userCB = NULL;
|
static CallBack userCB = NULL;
|
||||||
void Dump978Init(CallBack cb)
|
void Dump978Init(CallBack cb) {
|
||||||
{
|
|
||||||
make_atan2_table();
|
make_atan2_table();
|
||||||
init_fec();
|
init_fec();
|
||||||
userCB = cb;
|
userCB = cb;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void dump_raw_message(char updown, uint8_t *data, int len, int rs_errors)
|
static void dump_raw_message(char updown, uint8_t *data, int len,
|
||||||
{
|
int rs_errors) {
|
||||||
#ifndef BUILD_LIB
|
#ifndef BUILD_LIB
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -97,22 +95,21 @@ static void dump_raw_message(char updown, uint8_t *data, int len, int rs_errors)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_adsb_frame(uint64_t timestamp, uint8_t *frame, int rs)
|
static void handle_adsb_frame(uint64_t timestamp, uint8_t *frame, int rs) {
|
||||||
{
|
dump_raw_message('-', frame, (frame[0] >> 3) == 0 ? SHORT_FRAME_DATA_BYTES
|
||||||
dump_raw_message('-', frame, (frame[0]>>3) == 0 ? SHORT_FRAME_DATA_BYTES : LONG_FRAME_DATA_BYTES, rs);
|
: LONG_FRAME_DATA_BYTES,
|
||||||
|
rs);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_uplink_frame(uint64_t timestamp, uint8_t *frame, int rs)
|
static void handle_uplink_frame(uint64_t timestamp, uint8_t *frame, int rs) {
|
||||||
{
|
|
||||||
dump_raw_message('+', frame, UPLINK_FRAME_DATA_BYTES, rs);
|
dump_raw_message('+', frame, UPLINK_FRAME_DATA_BYTES, rs);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t iqphase[65536]; // contains value [0..65536) -> [0, 2*pi)
|
uint16_t iqphase[65536]; // contains value [0..65536) -> [0, 2*pi)
|
||||||
|
|
||||||
void make_atan2_table(void)
|
void make_atan2_table(void) {
|
||||||
{
|
|
||||||
unsigned i, q;
|
unsigned i, q;
|
||||||
union {
|
union {
|
||||||
uint8_t iq[2];
|
uint8_t iq[2];
|
||||||
|
@ -123,18 +120,20 @@ void make_atan2_table(void)
|
||||||
for (q = 0; q < 256; ++q) {
|
for (q = 0; q < 256; ++q) {
|
||||||
double d_i = (i - 127.5);
|
double d_i = (i - 127.5);
|
||||||
double d_q = (q - 127.5);
|
double d_q = (q - 127.5);
|
||||||
double ang = atan2(d_q, d_i) + M_PI; // atan2 returns [-pi..pi], normalize to [0..2*pi]
|
double ang = atan2(d_q, d_i) +
|
||||||
|
M_PI; // atan2 returns [-pi..pi], normalize to [0..2*pi]
|
||||||
double scaled_ang = round(32768 * ang / M_PI);
|
double scaled_ang = round(32768 * ang / M_PI);
|
||||||
|
|
||||||
u.iq[0] = i;
|
u.iq[0] = i;
|
||||||
u.iq[1] = q;
|
u.iq[1] = q;
|
||||||
iqphase[u.iq16] = (scaled_ang < 0 ? 0 : scaled_ang > 65535 ? 65535 : (uint16_t)scaled_ang);
|
iqphase[u.iq16] =
|
||||||
|
(scaled_ang < 0 ? 0 : scaled_ang > 65535 ? 65535
|
||||||
|
: (uint16_t)scaled_ang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_to_phi(uint16_t *buffer, int n)
|
static void convert_to_phi(uint16_t *buffer, int n) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
|
@ -142,8 +141,7 @@ static void convert_to_phi(uint16_t *buffer, int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BUILD_LIB
|
#ifndef BUILD_LIB
|
||||||
void read_from_stdin(void)
|
void read_from_stdin(void) {
|
||||||
{
|
|
||||||
char buffer[65536 * 2];
|
char buffer[65536 * 2];
|
||||||
int n;
|
int n;
|
||||||
int used = 0;
|
int used = 0;
|
||||||
|
@ -167,8 +165,7 @@ void read_from_stdin(void)
|
||||||
// #define DEFAULT_SAMPLE_RATE 2048000
|
// #define DEFAULT_SAMPLE_RATE 2048000
|
||||||
// #define DEFAULT_BUF_LENGTH (262144) 16*16384
|
// #define DEFAULT_BUF_LENGTH (262144) 16*16384
|
||||||
static char buffer[65536 * 2]; // 131072, max received should be 113120
|
static char buffer[65536 * 2]; // 131072, max received should be 113120
|
||||||
int process_data(char *data, int dlen)
|
int process_data(char *data, int dlen) {
|
||||||
{
|
|
||||||
int n;
|
int n;
|
||||||
int processed;
|
int processed;
|
||||||
int doffset = 0;
|
int doffset = 0;
|
||||||
|
@ -196,10 +193,8 @@ int process_data(char *data, int dlen)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Return 1 if word is "equal enough" to expected
|
// Return 1 if word is "equal enough" to expected
|
||||||
static inline int sync_word_fuzzy_compare(uint64_t word, uint64_t expected)
|
static inline int sync_word_fuzzy_compare(uint64_t word, uint64_t expected) {
|
||||||
{
|
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
|
|
||||||
if (word == expected)
|
if (word == expected)
|
||||||
|
@ -262,8 +257,7 @@ static inline int sync_word_fuzzy_compare(uint64_t word, uint64_t expected)
|
||||||
// that matches the sync word 'pattern'. Place the dphi
|
// that matches the sync word 'pattern'. Place the dphi
|
||||||
// threshold to use for bit slicing in '*center'. Return 1
|
// threshold to use for bit slicing in '*center'. Return 1
|
||||||
// if the sync word is OK, 0 on failure
|
// if the sync word is OK, 0 on failure
|
||||||
int check_sync_word(uint16_t *phi, uint64_t pattern, int16_t *center)
|
int check_sync_word(uint16_t *phi, uint64_t pattern, int16_t *center) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
int32_t dphi_zero_total = 0;
|
int32_t dphi_zero_total = 0;
|
||||||
int zero_bits = 0;
|
int zero_bits = 0;
|
||||||
|
@ -305,15 +299,15 @@ int check_sync_word(uint16_t *phi, uint64_t pattern, int16_t *center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//fprintf(stdout, "check_sync_word: center=%.0fkHz, errors=%d\n", *center * 2083334.0 / 65536 / 1000, error_bits);
|
// fprintf(stdout, "check_sync_word: center=%.0fkHz, errors=%d\n", *center *
|
||||||
|
// 2083334.0 / 65536 / 1000, error_bits);
|
||||||
|
|
||||||
return (error_bits <= MAX_SYNC_ERRORS);
|
return (error_bits <= MAX_SYNC_ERRORS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SYNC_MASK ((((uint64_t)1) << SYNC_BITS) - 1)
|
#define SYNC_MASK ((((uint64_t)1) << SYNC_BITS) - 1)
|
||||||
|
|
||||||
int process_buffer(uint16_t *phi, int len, uint64_t offset)
|
int process_buffer(uint16_t *phi, int len, uint64_t offset) {
|
||||||
{
|
|
||||||
uint64_t sync0 = 0, sync1 = 0;
|
uint64_t sync0 = 0, sync1 = 0;
|
||||||
int lenbits;
|
int lenbits;
|
||||||
int bit;
|
int bit;
|
||||||
|
@ -360,7 +354,8 @@ int process_buffer(uint16_t *phi, int len, uint64_t offset)
|
||||||
// errors.
|
// errors.
|
||||||
|
|
||||||
// check for downlink frames:
|
// check for downlink frames:
|
||||||
if (sync_word_fuzzy_compare(sync0, ADSB_SYNC_WORD) || sync_word_fuzzy_compare(sync1, ADSB_SYNC_WORD)) {
|
if (sync_word_fuzzy_compare(sync0, ADSB_SYNC_WORD) ||
|
||||||
|
sync_word_fuzzy_compare(sync1, ADSB_SYNC_WORD)) {
|
||||||
int startbit = (bit - SYNC_BITS + 1);
|
int startbit = (bit - SYNC_BITS + 1);
|
||||||
int shift = (sync_word_fuzzy_compare(sync0, ADSB_SYNC_WORD) ? 0 : 1);
|
int shift = (sync_word_fuzzy_compare(sync0, ADSB_SYNC_WORD) ? 0 : 1);
|
||||||
int index = startbit * 2 + shift;
|
int index = startbit * 2 + shift;
|
||||||
|
@ -384,7 +379,8 @@ int process_buffer(uint16_t *phi, int len, uint64_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for uplink frames:
|
// check for uplink frames:
|
||||||
else if (sync_word_fuzzy_compare(sync0, UPLINK_SYNC_WORD) || sync_word_fuzzy_compare(sync1, UPLINK_SYNC_WORD)) {
|
else if (sync_word_fuzzy_compare(sync0, UPLINK_SYNC_WORD) ||
|
||||||
|
sync_word_fuzzy_compare(sync1, UPLINK_SYNC_WORD)) {
|
||||||
int startbit = (bit - SYNC_BITS + 1);
|
int startbit = (bit - SYNC_BITS + 1);
|
||||||
int shift = (sync_word_fuzzy_compare(sync0, UPLINK_SYNC_WORD) ? 0 : 1);
|
int shift = (sync_word_fuzzy_compare(sync0, UPLINK_SYNC_WORD) ? 0 : 1);
|
||||||
int index = startbit * 2 + shift;
|
int index = startbit * 2 + shift;
|
||||||
|
@ -413,18 +409,26 @@ int process_buffer(uint16_t *phi, int len, uint64_t offset)
|
||||||
|
|
||||||
// demodulate 'bytes' bytes from samples at 'phi' into 'frame',
|
// demodulate 'bytes' bytes from samples at 'phi' into 'frame',
|
||||||
// using 'center_dphi' as the bit slicing threshold
|
// using 'center_dphi' as the bit slicing threshold
|
||||||
static void demod_frame(uint16_t *phi, uint8_t *frame, int bytes, int16_t center_dphi)
|
static void demod_frame(uint16_t *phi, uint8_t *frame, int bytes,
|
||||||
{
|
int16_t center_dphi) {
|
||||||
while (--bytes >= 0) {
|
while (--bytes >= 0) {
|
||||||
uint8_t b = 0;
|
uint8_t b = 0;
|
||||||
if (phi_difference(phi[0], phi[1]) > center_dphi) b |= 0x80;
|
if (phi_difference(phi[0], phi[1]) > center_dphi)
|
||||||
if (phi_difference(phi[2], phi[3]) > center_dphi) b |= 0x40;
|
b |= 0x80;
|
||||||
if (phi_difference(phi[4], phi[5]) > center_dphi) b |= 0x20;
|
if (phi_difference(phi[2], phi[3]) > center_dphi)
|
||||||
if (phi_difference(phi[6], phi[7]) > center_dphi) b |= 0x10;
|
b |= 0x40;
|
||||||
if (phi_difference(phi[8], phi[9]) > center_dphi) b |= 0x08;
|
if (phi_difference(phi[4], phi[5]) > center_dphi)
|
||||||
if (phi_difference(phi[10], phi[11]) > center_dphi) b |= 0x04;
|
b |= 0x20;
|
||||||
if (phi_difference(phi[12], phi[13]) > center_dphi) b |= 0x02;
|
if (phi_difference(phi[6], phi[7]) > center_dphi)
|
||||||
if (phi_difference(phi[14], phi[15]) > center_dphi) b |= 0x01;
|
b |= 0x10;
|
||||||
|
if (phi_difference(phi[8], phi[9]) > center_dphi)
|
||||||
|
b |= 0x08;
|
||||||
|
if (phi_difference(phi[10], phi[11]) > center_dphi)
|
||||||
|
b |= 0x04;
|
||||||
|
if (phi_difference(phi[12], phi[13]) > center_dphi)
|
||||||
|
b |= 0x02;
|
||||||
|
if (phi_difference(phi[14], phi[15]) > center_dphi)
|
||||||
|
b |= 0x01;
|
||||||
*frame++ = b;
|
*frame++ = b;
|
||||||
phi += 16;
|
phi += 16;
|
||||||
}
|
}
|
||||||
|
@ -436,8 +440,7 @@ static void demod_frame(uint16_t *phi, uint8_t *frame, int bytes, int16_t center
|
||||||
// number of corrected errors, or 9999 if demodulation failed.
|
// number of corrected errors, or 9999 if demodulation failed.
|
||||||
// Return 0 if demodulation failed, or the number of bits (not
|
// Return 0 if demodulation failed, or the number of bits (not
|
||||||
// samples) consumed if demodulation was OK.
|
// samples) consumed if demodulation was OK.
|
||||||
static int demod_adsb_frame(uint16_t *phi, uint8_t *to, int *rs_errors)
|
static int demod_adsb_frame(uint16_t *phi, uint8_t *to, int *rs_errors) {
|
||||||
{
|
|
||||||
int16_t center_dphi;
|
int16_t center_dphi;
|
||||||
int frametype;
|
int frametype;
|
||||||
|
|
||||||
|
@ -462,8 +465,7 @@ static int demod_adsb_frame(uint16_t *phi, uint8_t *to, int *rs_errors)
|
||||||
// number of corrected errors, or 9999 if demodulation failed.
|
// number of corrected errors, or 9999 if demodulation failed.
|
||||||
// Return 0 if demodulation failed, or the number of bits (not
|
// Return 0 if demodulation failed, or the number of bits (not
|
||||||
// samples) consumed if demodulation was OK.
|
// samples) consumed if demodulation was OK.
|
||||||
static int demod_uplink_frame(uint16_t *phi, uint8_t *to, int *rs_errors)
|
static int demod_uplink_frame(uint16_t *phi, uint8_t *to, int *rs_errors) {
|
||||||
{
|
|
||||||
int16_t center_dphi;
|
int16_t center_dphi;
|
||||||
uint8_t interleaved[UPLINK_FRAME_BYTES];
|
uint8_t interleaved[UPLINK_FRAME_BYTES];
|
||||||
|
|
||||||
|
@ -472,7 +474,8 @@ static int demod_uplink_frame(uint16_t *phi, uint8_t *to, int *rs_errors)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
demod_frame(phi + SYNC_BITS*2, interleaved, UPLINK_FRAME_BYTES, center_dphi);
|
demod_frame(phi + SYNC_BITS * 2, interleaved, UPLINK_FRAME_BYTES,
|
||||||
|
center_dphi);
|
||||||
|
|
||||||
// deinterleave and correct
|
// deinterleave and correct
|
||||||
if (correct_uplink_frame(interleaved, to, rs_errors) == 1)
|
if (correct_uplink_frame(interleaved, to, rs_errors) == 1)
|
||||||
|
|
Ładowanie…
Reference in New Issue