2016-02-21 13:57:35 -08:00
# include <stdlib.h>
2016-02-17 17:19:57 -08:00
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <unistd.h>
2016-02-21 16:52:36 -08:00
# include "airspy_adsb.h"
2016-02-17 17:19:57 -08:00
# include "beast.h"
2016-02-22 16:41:34 -08:00
# include "buf.h"
2016-02-22 16:58:13 -08:00
# include "packet.h"
2016-02-22 16:49:43 -08:00
# include "peer.h"
2016-02-17 17:19:57 -08:00
# include "raw.h"
# include "send.h"
2016-02-22 16:27:44 -08:00
# include "uuid.h"
2016-02-17 17:19:57 -08:00
# include "receive.h"
struct receive ;
typedef bool ( * parser_wrapper ) ( struct receive * , struct packet * ) ;
typedef bool ( * parser ) ( struct buf * , struct packet * , void * state ) ;
struct receive {
struct peer peer ;
char id [ UUID_LEN ] ;
struct buf buf ;
char parser_state [ PARSER_STATE_LEN ] ;
parser_wrapper parser_wrapper ;
parser parser ;
2016-02-23 12:08:53 -08:00
struct receive * prev ;
struct receive * next ;
2016-02-17 17:19:57 -08:00
} ;
2016-02-23 12:08:53 -08:00
struct receive * receive_head = NULL ;
2016-02-17 17:19:57 -08:00
struct parser {
char * name ;
parser parse ;
} parsers [ ] = {
2016-02-21 16:52:36 -08:00
{
. name = " airspy_adsb " ,
. parse = airspy_adsb_parse ,
} ,
2016-02-17 17:19:57 -08:00
{
. name = " beast " ,
. parse = beast_parse ,
} ,
{
. name = " raw " ,
. parse = raw_parse ,
} ,
} ;
# define NUM_PARSERS (sizeof(parsers) / sizeof(*parsers))
static bool receive_parse_wrapper ( struct receive * receive , struct packet * packet ) {
return receive - > parser ( & receive - > buf , packet , receive - > parser_state ) ;
}
static bool receive_autodetect_parse ( struct receive * receive , struct packet * packet ) {
struct buf * buf = & receive - > buf ;
void * state = receive - > parser_state ;
for ( int i = 0 ; i < NUM_PARSERS ; i + + ) {
if ( parsers [ i ] . parse ( buf , packet , state ) ) {
fprintf ( stderr , " R %s: Detected input format %s \n " , receive - > id , parsers [ i ] . name ) ;
receive - > parser_wrapper = receive_parse_wrapper ;
receive - > parser = parsers [ i ] . parse ;
return true ;
}
}
return false ;
}
2016-02-21 13:57:35 -08:00
static void receive_del ( struct receive * receive ) {
assert ( ! close ( receive - > peer . fd ) ) ;
2016-02-23 12:08:53 -08:00
if ( receive - > prev ) {
receive - > prev - > next = receive - > next ;
} else {
receive_head = receive - > next ;
}
if ( receive - > next ) {
receive - > next - > prev = receive - > prev ;
}
2016-02-21 13:57:35 -08:00
free ( receive ) ;
}
2016-02-17 17:19:57 -08:00
static void receive_read ( struct peer * peer ) {
struct receive * receive = ( struct receive * ) peer ;
if ( buf_fill ( & receive - > buf , receive - > peer . fd ) < = 0 ) {
fprintf ( stderr , " R %s: Connection closed by peer \n " , receive - > id ) ;
2016-02-21 13:57:35 -08:00
receive_del ( receive ) ;
2016-02-17 17:19:57 -08:00
return ;
}
2016-02-22 22:00:49 -08:00
struct packet packet = {
. source_id = receive - > id ,
} ;
2016-02-17 17:19:57 -08:00
while ( receive - > parser_wrapper ( receive , & packet ) ) {
send_write ( & packet ) ;
}
if ( receive - > buf . length = = BUF_LEN_MAX ) {
fprintf ( stderr , " R %s: Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking. \n " , receive - > id ) ;
2016-02-21 13:57:35 -08:00
receive_del ( receive ) ;
2016-02-17 17:19:57 -08:00
return ;
}
}
2016-02-23 12:08:53 -08:00
void receive_cleanup ( ) {
while ( receive_head ) {
receive_del ( receive_head ) ;
}
}
2016-02-17 17:19:57 -08:00
void receive_new ( int fd , void * unused ) {
struct receive * receive = malloc ( sizeof ( * receive ) ) ;
assert ( receive ) ;
uuid_gen ( receive - > id ) ;
receive - > peer . fd = fd ;
buf_init ( & receive - > buf ) ;
memset ( receive - > parser_state , 0 , PARSER_STATE_LEN ) ;
receive - > parser_wrapper = receive_autodetect_parse ;
2016-02-23 12:08:53 -08:00
receive - > prev = NULL ;
receive - > next = receive_head ;
receive_head = receive ;
2016-02-17 17:19:57 -08:00
receive - > peer . event_handler = receive_read ;
peer_epoll_add ( ( struct peer * ) receive , EPOLLIN ) ;
2016-02-17 18:02:56 -08:00
fprintf ( stderr , " R %s: New receive connection \n " , receive - > id ) ;
2016-02-17 17:19:57 -08:00
}
void receive_print_usage ( ) {
2016-02-17 20:15:56 -08:00
fprintf ( stderr , " \n Supported receive formats (auto-detected): \n " ) ;
2016-02-17 17:19:57 -08:00
for ( int i = 0 ; i < NUM_PARSERS ; i + + ) {
fprintf ( stderr , " \t %s \n " , parsers [ i ] . name ) ;
}
}