25 #include "application.hh" 29 #include "dripline_constants.hh" 31 #include <arpa/inet.h> 34 #include <netinet/in.h> 40 #include <sys/socket.h> 41 #include <sys/types.h> 54 int main(
int argc,
char** argv )
59 scarab::main_app the_main;
62 scarab::param_node t_default_config;
63 t_default_config.add(
"n", scarab::param_value( 1U ) );
64 t_default_config.add(
"ip", scarab::param_value(
"127.0.0.1" ) );
65 t_default_config.add(
"port", scarab::param_value( 23530U ) );
66 t_default_config.add(
"interface", scarab::param_value(
"eth1" ) );
67 t_default_config.add(
"timeout", scarab::param_value( 10U ) );
68 t_default_config.add(
"max-packet-size", scarab::param_value( 16384U ) );
69 t_default_config.add(
"packet-type", scarab::param_value(
"roach" ) );
70 the_main.default_config() = t_default_config;
73 the_main.add_config_option<
unsigned >(
"-n,--n-packets",
"n",
"Number of packets to grab" );
74 the_main.add_config_option< std::string >(
"--ip",
"ip",
"IP address from which to receive packets" );
75 the_main.add_config_option<
unsigned >(
"-p,--port",
"port",
"Port on which to receive packets" );
76 the_main.add_config_option< std::string >(
"-i,--interface",
"interface",
"Ethernet interface to grab packets off of" );
77 the_main.add_config_option<
unsigned >(
"-t,--timeout",
"timeout",
"Timeout" );
78 the_main.add_config_option<
unsigned >(
"-m,--max-packet-size",
"max-packet-size",
"Maximum packet size" );
79 the_main.add_config_option< std::string >(
"---packet-type",
"packet-type",
"Packet type" );
85 the_main.callback( [&]() {
86 unsigned t_n_packets( the_main.master_config()[
"n"]().as_uint() );
87 std::string t_ip( the_main.master_config()[
"ip"]().as_string() );
88 unsigned t_port = the_main.master_config()[
"port"]().as_uint();
89 std::string t_interface( the_main.master_config()[
"interface"]().as_string() );
90 unsigned t_timeout_sec = the_main.master_config()[
"timeout"]().as_uint();
92 unsigned t_max_packet_size = the_main.master_config()[
"max-packet-size"]().as_uint();
93 std::string t_packet_type( the_main.master_config()[
"packet-type"]().as_string() );
95 bool (*t_proc_pkt_func)( uint8_t* ) =
nullptr;
96 if( t_packet_type ==
"roach" )
99 LDEBUG(
plog,
"Processing packets as ROACH packets" );
101 else if( t_packet_type ==
"unknown" )
104 LDEBUG(
plog,
"Processing packets as unknown packets" );
108 throw error() <<
"Unknown packet type supplied: " << t_packet_type;
112 LDEBUG(
plog,
"Opening UDP socket receiving at " << t_ip <<
":" << t_port );
115 socklen_t t_socket_length =
sizeof(sockaddr_in);
116 sockaddr_in* t_address =
new sockaddr_in();
117 ::memset( t_address, 0, t_socket_length );
120 t_address->sin_family = AF_INET;
121 t_address->sin_addr.s_addr = inet_addr( t_ip.c_str() );
122 if( t_address->sin_addr.s_addr == INADDR_NONE )
124 throw error() <<
"Invalid IP address";
126 t_address->sin_port = htons( t_port );
131 int t_socket = ::socket( AF_INET, SOCK_DGRAM, 0 );
134 throw error() <<
"Could not create socket:\n\t" << strerror( errno );
143 ::setsockopt( t_socket, SOL_SOCKET, SO_REUSEADDR, (
const void *)&optval ,
sizeof(
int));
146 if( t_timeout_sec > 0 )
148 struct timeval t_timeout;
149 t_timeout.tv_sec = t_timeout_sec;
150 t_timeout.tv_usec = 0;
151 ::setsockopt( t_socket, SOL_SOCKET, SO_RCVTIMEO, (
char *)&t_timeout,
sizeof(
struct timeval) );
157 if( ::bind( t_socket, (
const sockaddr*) (t_address), t_socket_length ) < 0 )
159 throw error() <<
"Could not bind socket:\n\t" << strerror( errno );
164 uint8_t* t_buffer =
new uint8_t [t_max_packet_size];
166 for(
unsigned i_packet = 0; i_packet < t_n_packets; ++i_packet )
168 LINFO(
plog,
"Waiting for next packet" );
169 ssize_t t_size_received = 0;
170 while( t_size_received <= 0 )
172 t_size_received = ::recv( t_socket, (
void*)t_buffer, t_max_packet_size, 0 );
174 if( t_size_received > 0 )
176 LINFO(
plog,
"Packet received (" << t_size_received <<
" bytes)" );
178 if( ! (*t_proc_pkt_func)( t_buffer ) )
180 LWARN(
plog,
"Packet not processed correctly" );
187 if( t_address !=
nullptr )
202 CLI11_PARSE( the_main, argc, argv );
204 return RETURN_SUCCESS;
206 catch( std::exception& e )
208 LERROR(
plog,
"Caught an exception: " << e.what() );
222 LDEBUG(
plog,
"Raw packet header: " << std::hex << t_raw_packet->
f_word_0 <<
", " << t_raw_packet->
f_word_1 <<
", " << t_raw_packet->
f_word_2 <<
", " << t_raw_packet->
f_word_3 );
223 LDEBUG(
plog,
"Raw packet data, first 8 bins, true order: " << (
int)t_raw_packet->
f_data[0] <<
", " << (
int)t_raw_packet->
f_data[1] <<
"; " << (
int)t_raw_packet->
f_data[2] <<
", " << (
int)t_raw_packet->
f_data[3] <<
"; " << (
int)t_raw_packet->
f_data[4] <<
", " << (
int)t_raw_packet->
f_data[5] <<
"; " << (
int)t_raw_packet->
f_data[6] <<
", " << (
int)t_raw_packet->
f_data[7] );
226 LINFO(
plog,
"ROACH data received:\n" 227 " digital_id (channel) = " << t_roach_packet->
f_digital_id <<
'\n' <<
228 " unix time = " << t_roach_packet->
f_unix_time <<
'\n' <<
231 " if id = " << t_roach_packet->
f_if_id <<
'\n' <<
232 " first 8 bins (true order) = " << (
int)t_roach_packet->
f_data[ 0 ] <<
", " << (
int)t_roach_packet->
f_data[ 1 ] <<
"; " << (
int)t_roach_packet->
f_data[ 2 ] <<
", " << (
int)t_roach_packet->
f_data[ 3 ] <<
"; " << (
int)t_roach_packet->
f_data[ 4 ] <<
", " << (
int)t_roach_packet->
f_data[ 5 ] <<
"; " << (
int)t_roach_packet->
f_data[ 6 ] <<
", " << (
int)t_roach_packet->
f_data[ 7 ] );
static scarab::logger plog("batch_executor")
void byteswap_inplace(raw_roach_packet *a_pkt)
int main(int argc, char **argv)
bool ProcessROACHPacket(uint8_t *a_buffer)
bool ProcessUnknownPacket(uint8_t *a_buffer)
LOGGER(plog, "egg_writer")