2016-02-15 20:01:48 +00:00
# include <stdio.h>
# include <assert.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netdb.h>
# include <sys/epoll.h>
2016-02-15 21:12:26 +00:00
# include <string.h>
2016-02-15 20:01:48 +00:00
# include "airspy_adsb.h"
2016-02-16 03:42:41 +00:00
# include "beast.h"
2016-02-16 02:28:05 +00:00
# include "client.h"
2016-02-15 20:01:48 +00:00
# include "backend.h"
2016-02-15 21:12:26 +00:00
bool backend_autodetect_parse ( struct backend * , struct packet * ) ;
2016-02-15 20:01:48 +00:00
static parser parsers [ ] = {
airspy_adsb_parse ,
2016-02-16 03:42:41 +00:00
beast_parse ,
2016-02-15 20:01:48 +00:00
} ;
# define NUM_PARSERS (sizeof(parsers) / sizeof(*parsers))
2016-02-15 21:12:26 +00:00
void backend_init ( struct backend * backend ) {
backend - > type = PEER_BACKEND ;
backend - > fd = - 1 ;
buf_init ( & backend - > buf ) ;
memset ( backend - > parser_state , 0 , PARSER_STATE_LEN ) ;
backend - > parser = backend_autodetect_parse ;
}
2016-02-15 20:01:48 +00:00
bool backend_connect ( char * node , char * service , struct backend * backend , int epoll_fd ) {
assert ( backend - > type = = PEER_BACKEND ) ;
2016-02-16 02:28:05 +00:00
uuid_gen ( backend - > id ) ;
2016-02-15 21:22:23 +00:00
2016-02-15 20:01:48 +00:00
struct addrinfo * addrs ;
{
struct addrinfo hints = {
. ai_family = AF_UNSPEC ,
. ai_socktype = SOCK_STREAM ,
} ;
int gai_err = getaddrinfo ( node , service , & hints , & addrs ) ;
if ( gai_err ) {
2016-02-17 00:21:28 +00:00
fprintf ( stderr , " B %s: getaddrinfo(%s %s): %s \n " , backend - > id , node , service , gai_strerror ( gai_err ) ) ;
2016-02-15 20:01:48 +00:00
return false ;
}
}
{
struct addrinfo * addr ;
for ( addr = addrs ; addr ! = NULL ; addr = addr - > ai_next ) {
backend - > fd = socket ( addr - > ai_family , addr - > ai_socktype , addr - > ai_protocol ) ;
if ( backend - > fd = = - 1 ) {
perror ( " socket " ) ;
continue ;
}
if ( connect ( backend - > fd , addr - > ai_addr , addr - > ai_addrlen ) ! = - 1 ) {
break ;
}
close ( backend - > fd ) ;
}
if ( addr = = NULL ) {
freeaddrinfo ( addrs ) ;
2016-02-17 00:21:28 +00:00
fprintf ( stderr , " B %s: Can't connect to %s %s \n " , backend - > id , node , service ) ;
2016-02-15 20:01:48 +00:00
return false ;
}
char hbuf [ NI_MAXHOST ] , sbuf [ NI_MAXSERV ] ;
if ( getnameinfo ( addr - > ai_addr , addr - > ai_addrlen , hbuf , sizeof ( hbuf ) , sbuf , sizeof ( sbuf ) , NI_NUMERICHOST | NI_NUMERICSERV ) = = 0 ) {
2016-02-17 00:21:28 +00:00
fprintf ( stderr , " B %s: Connected to %s %s \n " , backend - > id , hbuf , sbuf ) ;
2016-02-15 20:01:48 +00:00
}
}
freeaddrinfo ( addrs ) ;
{
struct epoll_event ev = {
. events = EPOLLIN ,
. data = {
. ptr = backend ,
} ,
} ;
if ( epoll_ctl ( epoll_fd , EPOLL_CTL_ADD , backend - > fd , & ev ) = = - 1 ) {
perror ( " epoll_ctl " ) ;
return false ;
}
}
return true ;
}
bool backend_read ( struct backend * backend ) {
if ( buf_fill ( & backend - > buf , backend - > fd ) < 0 ) {
2016-02-17 00:21:28 +00:00
fprintf ( stderr , " B %s: Connection closed by backend \n " , backend - > id ) ;
2016-02-15 20:01:48 +00:00
return false ;
}
2016-02-17 00:21:28 +00:00
struct packet packet = {
. backend = backend ,
} ;
2016-02-15 20:01:48 +00:00
while ( backend - > parser ( backend , & packet ) ) {
2016-02-16 02:28:05 +00:00
client_write ( & packet ) ;
2016-02-15 20:01:48 +00:00
}
if ( backend - > buf . length = = BUF_LEN_MAX ) {
2016-02-17 00:21:28 +00:00
fprintf ( stderr , " B %s: Input buffer overrun. This probably means that adsbus doesn't understand the protocol that this source is speaking. \n " , backend - > id ) ;
2016-02-15 20:01:48 +00:00
return false ;
}
return true ;
}
bool backend_autodetect_parse ( struct backend * backend , struct packet * packet ) {
assert ( backend - > type = = PEER_BACKEND ) ;
for ( int i = 0 ; i < NUM_PARSERS ; i + + ) {
if ( parsers [ i ] ( backend , packet ) ) {
backend - > parser = parsers [ i ] ;
return true ;
}
}
return false ;
}