2008-02-14 08:54:51 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the rtap localisation project.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-10-06 17:27:33 +02:00
|
|
|
#include "owlps-listener.h"
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-03-29 18:30:00 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <net/if.h>
|
2011-06-24 16:10:09 +02:00
|
|
|
#include <net/ethernet.h>
|
2011-03-29 18:30:00 +02:00
|
|
|
|
|
|
|
#ifdef USE_CONFIG_FILE
|
|
|
|
# include <confuse.h>
|
|
|
|
#endif // USE_CONFIG_FILE
|
|
|
|
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
# include <pthread.h>
|
2011-06-23 13:30:57 +02:00
|
|
|
# include <iwlib.h>
|
2011-03-29 18:30:00 +02:00
|
|
|
#endif // USE_PTHREAD
|
|
|
|
|
|
|
|
// Used by get_mac_addr():
|
|
|
|
#include <netinet/udp.h>
|
|
|
|
#include <netinet/ip.h>
|
2011-06-23 13:16:58 +02:00
|
|
|
#include <arpa/inet.h>
|
2009-09-03 11:09:48 +02:00
|
|
|
|
2011-04-06 18:11:14 +02:00
|
|
|
#include <assert.h>
|
|
|
|
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
char *program_name = NULL ;
|
2011-03-24 23:42:42 +01:00
|
|
|
uint8_t my_mac_bytes[ETHER_ADDR_LEN] ; // AP MAC address
|
2011-03-24 08:40:35 +01:00
|
|
|
char my_ip[INET_ADDRSTRLEN] ; // AP IP address
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-03-24 14:57:33 +01:00
|
|
|
pcap_t *capture_handler = NULL ; // Packet capture descriptor
|
2010-08-03 11:05:06 +02:00
|
|
|
int aggregation_sockfd ;
|
|
|
|
struct sockaddr_in aggregation_server ;
|
2011-04-06 18:11:14 +02:00
|
|
|
|
|
|
|
#ifdef USE_PTHREAD
|
2010-10-12 10:13:59 +02:00
|
|
|
int autocalibration_send_sockfd ;
|
|
|
|
struct sockaddr_in autocalibration_send_server ;
|
2011-04-06 18:11:14 +02:00
|
|
|
// TRUE if the coordinates of the listener were provided by the user:
|
|
|
|
owl_bool coordinates_provided = FALSE ;
|
|
|
|
#endif // USE_PTHREAD
|
2010-08-03 11:05:06 +02:00
|
|
|
|
2009-07-02 13:12:51 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
2010-07-13 14:39:03 +02:00
|
|
|
cfg_t *cfg ; // Configuration structure
|
2009-07-02 13:12:51 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
#else // USE_CONFIG_FILE
|
|
|
|
/* If we do not use libconfuse, we declare a structure to store getopt
|
|
|
|
* options.
|
|
|
|
*/
|
|
|
|
struct {
|
2009-08-04 12:02:52 +02:00
|
|
|
char mode ;
|
2011-03-24 08:40:35 +01:00
|
|
|
char aggregation_ip[INET_ADDRSTRLEN] ;
|
2011-03-10 19:18:43 +01:00
|
|
|
uint_fast16_t aggregation_port ;
|
|
|
|
uint_fast16_t listening_port ;
|
2009-07-02 13:12:51 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool keep_monitor ;
|
2009-07-02 13:12:51 +02:00
|
|
|
#endif // USE_PTHREAD
|
|
|
|
char rtap_iface[IFNAMSIZ + 1] ;
|
|
|
|
char wifi_iface[IFNAMSIZ + 1] ;
|
2010-10-08 16:57:40 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool autocalibration ;
|
2011-03-24 08:40:35 +01:00
|
|
|
char autocalibration_ip[INET_ADDRSTRLEN] ;
|
2011-03-10 19:18:43 +01:00
|
|
|
uint_fast16_t autocalibration_request_port ;
|
|
|
|
uint_fast16_t autocalibration_port ;
|
|
|
|
uint_fast32_t autocalibration_hello_delay ;
|
|
|
|
uint_fast32_t autocalibration_delay ;
|
|
|
|
uint_fast16_t autocalibration_nb_packets ;
|
2011-04-06 18:11:14 +02:00
|
|
|
owl_direction my_direction ;
|
|
|
|
float my_position_x ;
|
|
|
|
float my_position_y ;
|
|
|
|
float my_position_z ;
|
2010-10-08 16:57:40 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-07-24 17:58:40 +02:00
|
|
|
uint_fast8_t verbose ;
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool display_captured ;
|
2010-07-13 14:39:03 +02:00
|
|
|
} options = { // Initalise default options:
|
2009-08-04 12:02:52 +02:00
|
|
|
MODE_ACTIVE,
|
2009-07-02 13:12:51 +02:00
|
|
|
"127.0.0.1",
|
|
|
|
AGGREGATE_DEFAULT_PORT,
|
2009-11-09 10:42:23 +01:00
|
|
|
LOC_REQUEST_DEFAULT_PORT,
|
2009-07-02 13:12:51 +02:00
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
FALSE,
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
"",
|
2009-08-04 12:02:52 +02:00
|
|
|
"",
|
2010-10-08 16:57:40 +02:00
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
FALSE,
|
2011-02-23 18:03:00 +01:00
|
|
|
"",
|
2011-02-04 17:54:17 +01:00
|
|
|
DEFAULT_AUTOCALIBRATION_REQUEST_PORT,
|
2010-10-14 18:30:41 +02:00
|
|
|
DEFAULT_AUTOCALIBRATION_PORT,
|
|
|
|
DEFAULT_AUTOCALIBRATION_HELLO_DELAY,
|
|
|
|
DEFAULT_AUTOCALIBRATION_DELAY,
|
|
|
|
DEFAULT_AUTOCALIBRATION_NBPKT,
|
2011-04-06 18:11:14 +02:00
|
|
|
0, 0, 0, 0,
|
2010-10-08 16:57:40 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-07-24 17:58:40 +02:00
|
|
|
0,
|
2009-08-04 12:02:52 +02:00
|
|
|
FALSE
|
2009-07-02 13:12:51 +02:00
|
|
|
} ;
|
|
|
|
#endif // USE_CONFIG_FILE
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2008-02-22 16:04:49 +01:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
|
2008-02-14 08:54:51 +01:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
struct sigaction action ; // Signal handler structure
|
|
|
|
int ret ; // Program return value
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2010-10-08 16:57:40 +02:00
|
|
|
pthread_t
|
|
|
|
keep_monitor_thread,
|
2010-10-12 10:13:59 +02:00
|
|
|
autocalibration_thread,
|
2010-10-08 16:57:40 +02:00
|
|
|
autocalibration_hello_thread ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_PTHREAD
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
program_name = argv[0] ;
|
|
|
|
initialise_configuration(argc, argv) ;
|
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
owl_run = TRUE ;
|
2010-07-13 15:09:07 +02:00
|
|
|
|
|
|
|
/* Set up signal handlers */
|
|
|
|
sigemptyset(&action.sa_mask) ;
|
2011-03-24 14:57:33 +01:00
|
|
|
action.sa_handler = sigint_handler ;
|
2010-07-13 15:09:07 +02:00
|
|
|
sigaction(SIGINT, &action, NULL) ;
|
2011-03-24 14:57:33 +01:00
|
|
|
action.sa_handler = sigterm_handler ;
|
2010-07-13 15:09:07 +02:00
|
|
|
sigaction(SIGTERM, &action, NULL) ;
|
|
|
|
|
2011-03-10 19:20:40 +01:00
|
|
|
get_mac_addr(GET_WIFI_IFACE(), my_mac_bytes) ;
|
2010-10-21 16:34:53 +02:00
|
|
|
get_ip_addr(GET_WIFI_IFACE(), my_ip) ;
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
|
|
|
{
|
|
|
|
printf("My MAC address is: %s\n",
|
|
|
|
owl_mac_bytes_to_string(my_mac_bytes)) ;
|
|
|
|
printf("My IP address is: %s\n", my_ip) ;
|
|
|
|
}
|
2010-10-21 16:34:53 +02:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2010-10-08 16:57:40 +02:00
|
|
|
/* Set up threads */
|
2010-07-13 15:09:07 +02:00
|
|
|
if (GET_KEEP_MONITOR())
|
2011-03-24 08:30:54 +01:00
|
|
|
{
|
|
|
|
ret = pthread_create(&keep_monitor_thread, NULL,
|
|
|
|
&keep_mode_monitor, GET_WIFI_IFACE()) ;
|
|
|
|
if (ret != 0)
|
|
|
|
{
|
|
|
|
perror("Cannot create keep monitor thread") ;
|
|
|
|
ret = ERR_CREATING_THREAD ;
|
|
|
|
goto exit ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-08 16:57:40 +02:00
|
|
|
if (GET_AUTOCALIBRATION())
|
|
|
|
{
|
2011-03-24 08:30:54 +01:00
|
|
|
ret = pthread_create(&autocalibration_thread, NULL,
|
|
|
|
&autocalibrate, NULL) ;
|
|
|
|
if (ret != 0)
|
|
|
|
{
|
|
|
|
perror("Cannot create autocalibration thread") ;
|
|
|
|
ret = ERR_CREATING_THREAD ;
|
|
|
|
goto exit ;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = pthread_create(&autocalibration_hello_thread, NULL,
|
|
|
|
&autocalibrate_hello, NULL) ;
|
|
|
|
if (ret != 0)
|
|
|
|
{
|
|
|
|
perror("Cannot create autocalibration hello thread") ;
|
|
|
|
ret = ERR_CREATING_THREAD ;
|
|
|
|
goto exit ;
|
|
|
|
}
|
2010-10-08 16:57:40 +02:00
|
|
|
}
|
2010-07-13 15:09:07 +02:00
|
|
|
#endif // USE_PTHREAD
|
|
|
|
|
|
|
|
ret = capture() ; // Capture loop
|
|
|
|
|
2011-03-24 08:30:54 +01:00
|
|
|
/* Wait for the threads to terminate */
|
|
|
|
|
2011-06-24 15:38:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-03-24 08:30:54 +01:00
|
|
|
if (GET_KEEP_MONITOR())
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
|
|
|
fprintf(stderr, "Waiting for the keep mode monitor thread... ") ;
|
2011-03-24 08:30:54 +01:00
|
|
|
if (pthread_join(keep_monitor_thread, NULL) != 0)
|
|
|
|
perror("Cannot join keep mode monitor thread") ;
|
2011-07-24 18:32:06 +02:00
|
|
|
else if (VERBOSE_WARNING)
|
2011-03-24 08:30:54 +01:00
|
|
|
fprintf(stderr, "OK.\n") ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GET_AUTOCALIBRATION())
|
|
|
|
{
|
|
|
|
// We must cancel this thread because it can be blocked on the
|
|
|
|
// recvfrom() call:
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
|
|
|
fprintf(stderr, "Cancelling the autocalibration thread... ") ;
|
2011-03-24 08:30:54 +01:00
|
|
|
if (pthread_cancel(autocalibration_thread) != 0)
|
|
|
|
perror("Cannot cancel autocalibration thread") ;
|
2011-07-24 18:32:06 +02:00
|
|
|
else if (VERBOSE_WARNING)
|
2011-03-24 08:30:54 +01:00
|
|
|
fprintf(stderr, "OK.\n") ;
|
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
|
|
|
fprintf(stderr, "Waiting for the autocalibration thread... ") ;
|
2011-03-24 08:30:54 +01:00
|
|
|
if (pthread_join(autocalibration_thread, NULL) != 0)
|
|
|
|
perror("Cannot join autocalibration thread") ;
|
2011-07-24 18:32:06 +02:00
|
|
|
else if (VERBOSE_WARNING)
|
2011-03-24 08:30:54 +01:00
|
|
|
fprintf(stderr, "OK.\n") ;
|
|
|
|
|
|
|
|
// We must cancel this thread if we do not want to wait
|
|
|
|
// autocalibration_hello_delay seconds (in the worst case):
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
|
|
|
fprintf(stderr,
|
|
|
|
"Cancelling the autocalibration hello thread... ") ;
|
2011-03-24 08:30:54 +01:00
|
|
|
if (pthread_cancel(autocalibration_hello_thread) != 0)
|
|
|
|
perror("Cannot cancel autocalibration hello thread") ;
|
2011-07-24 18:32:06 +02:00
|
|
|
else if (VERBOSE_WARNING)
|
2011-03-24 08:30:54 +01:00
|
|
|
fprintf(stderr, "OK.\n") ;
|
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
|
|
|
fprintf(stderr,
|
|
|
|
"Waiting for the autocalibration hello thread... ") ;
|
2011-03-24 08:30:54 +01:00
|
|
|
if (pthread_join(autocalibration_hello_thread, NULL) != 0)
|
|
|
|
perror("Cannot join autocalibration hello thread") ;
|
2011-07-24 18:32:06 +02:00
|
|
|
else if (VERBOSE_WARNING)
|
2011-03-24 08:30:54 +01:00
|
|
|
fprintf(stderr, "OK.\n") ;
|
|
|
|
}
|
2011-06-24 15:38:07 +02:00
|
|
|
#else // USE_PTHREAD
|
|
|
|
// Just to avoid a warning when compiling without threads' support:
|
|
|
|
goto exit ;
|
|
|
|
#endif // USE_PTHREAD
|
2011-03-24 08:30:54 +01:00
|
|
|
|
|
|
|
/* Last cleaning tasks */
|
|
|
|
exit:
|
2010-07-13 15:09:07 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
|
|
|
cfg_free(cfg) ; // Clean configuration
|
|
|
|
#endif // USE_CONFIG_FILE
|
|
|
|
|
|
|
|
printf("%s: end.\n", program_name) ;
|
|
|
|
return ret ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void initialise_configuration(int argc, char **argv)
|
|
|
|
{
|
|
|
|
parse_config_file(argc, argv) ;
|
|
|
|
parse_command_line(argc, argv) ;
|
|
|
|
check_configuration() ;
|
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
|
|
|
print_configuration() ;
|
2010-07-13 15:09:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void parse_config_file(int argc, char **argv)
|
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
|
|
|
// If we use libconfuse, we declare options:
|
|
|
|
cfg_opt_t opts[] =
|
|
|
|
{
|
|
|
|
// Listening mode: a for active, p for passive, m for mixed
|
|
|
|
// (default: a):
|
|
|
|
CFG_INT("mode", MODE_ACTIVE, CFGF_NONE),
|
|
|
|
// IP address of the aggregator (default: loopback):
|
|
|
|
CFG_STR("aggregation_ip", "127.0.0.1", CFGF_NONE),
|
|
|
|
// Port on which the aggregator listens:
|
|
|
|
CFG_INT("aggregation_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE),
|
|
|
|
// Port on which mobiles send active requests:
|
|
|
|
CFG_INT("listening_port", LOC_REQUEST_DEFAULT_PORT, CFGF_NONE),
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2010-07-13 14:39:03 +02:00
|
|
|
// Activate the active monitor mode keeping-up (read the code if
|
|
|
|
// you do not understand what I mean):
|
|
|
|
CFG_BOOL("keep_monitor", cfg_false, CFGF_NONE),
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_PTHREAD
|
2010-07-13 14:39:03 +02:00
|
|
|
// Radiotap interface, used to capture:
|
|
|
|
CFG_STR("rtap_iface", "", CFGF_NONE),
|
|
|
|
// Physical interface corresponding to the radiotap interface (used
|
|
|
|
// to get the MAC address):
|
|
|
|
CFG_STR("wifi_iface", "", CFGF_NONE),
|
2010-10-08 16:57:40 +02:00
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
// Autocalibration activated?
|
|
|
|
CFG_BOOL("autocalibration", cfg_false, CFGF_NONE),
|
2011-02-23 18:03:00 +01:00
|
|
|
// Destination IP address of the autocalibration requests (default:
|
|
|
|
// none, but will be set to aggregation_ip in the config check):
|
|
|
|
CFG_STR("autocalibration_ip", "", CFGF_NONE),
|
2011-02-04 17:54:17 +01:00
|
|
|
// Port on which autocalibration requests are sent:
|
|
|
|
CFG_INT("autocalibration_request_port",
|
|
|
|
DEFAULT_AUTOCALIBRATION_REQUEST_PORT, CFGF_NONE),
|
2010-10-08 16:57:40 +02:00
|
|
|
// Port on which autocalibration data are exchanged:
|
2010-10-14 18:30:41 +02:00
|
|
|
CFG_INT("autocalibration_port", DEFAULT_AUTOCALIBRATION_PORT,
|
2010-10-08 16:57:40 +02:00
|
|
|
CFGF_NONE),
|
|
|
|
// Delay between two hello messages:
|
|
|
|
CFG_INT("autocalibration_hello_delay",
|
2010-10-14 18:30:41 +02:00
|
|
|
DEFAULT_AUTOCALIBRATION_HELLO_DELAY,
|
2010-10-08 16:57:40 +02:00
|
|
|
CFGF_NONE),
|
2010-10-12 10:13:59 +02:00
|
|
|
// Delay between two calibration packet transmission:
|
2010-10-14 18:30:41 +02:00
|
|
|
CFG_INT("autocalibration_delay", DEFAULT_AUTOCALIBRATION_DELAY,
|
2010-10-12 10:13:59 +02:00
|
|
|
CFGF_NONE),
|
|
|
|
// Number of packets for a calibration request:
|
|
|
|
CFG_INT("autocalibration_nb_packets",
|
2010-10-14 18:30:41 +02:00
|
|
|
DEFAULT_AUTOCALIBRATION_NBPKT, CFGF_NONE),
|
2011-04-06 18:11:14 +02:00
|
|
|
// Direction
|
|
|
|
CFG_INT("my_direction", 0, CFGF_NONE),
|
|
|
|
// Position X
|
|
|
|
CFG_FLOAT("my_position_x", 0, CFGF_NONE),
|
|
|
|
// Position Y
|
|
|
|
CFG_FLOAT("my_position_y", 0, CFGF_NONE),
|
|
|
|
// Position Z
|
|
|
|
CFG_FLOAT("my_position_z", 0, CFGF_NONE),
|
2010-10-08 16:57:40 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-07-24 17:58:40 +02:00
|
|
|
// Verbose level:
|
|
|
|
CFG_INT("verbose", 0, CFGF_NONE),
|
2011-02-23 17:18:17 +01:00
|
|
|
// Display captured packets, or not:
|
|
|
|
CFG_BOOL("display_captured", cfg_false, CFGF_NONE),
|
2010-07-13 14:39:03 +02:00
|
|
|
CFG_END()
|
|
|
|
} ;
|
|
|
|
|
2010-10-20 17:55:26 +02:00
|
|
|
char *config_file = NULL ; // Configuration file name
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_CONFIG_FILE
|
|
|
|
|
2010-10-20 17:55:26 +02:00
|
|
|
// Option -f specifies a config file, options -h and -V exit the
|
|
|
|
// program, so we search for them first
|
2010-07-13 15:09:07 +02:00
|
|
|
int opt ;
|
2010-10-20 17:55:26 +02:00
|
|
|
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2010-10-20 17:55:26 +02:00
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'f' :
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
2010-10-20 17:55:26 +02:00
|
|
|
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ;
|
|
|
|
strcpy(config_file, optarg) ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#else // USE_CONFIG_FILE
|
2010-10-20 17:55:26 +02:00
|
|
|
fprintf(stderr, "Warning! Program was not compiled with"
|
|
|
|
" configuration file support, so -f is not available."
|
|
|
|
" You must specify all options on the command line,"
|
|
|
|
" or default value will be used.\n") ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_CONFIG_FILE
|
2011-04-12 22:20:39 +02:00
|
|
|
break ;
|
2010-10-20 17:55:26 +02:00
|
|
|
case 'h' :
|
|
|
|
print_usage() ;
|
|
|
|
exit(0) ;
|
|
|
|
case 'V' :
|
|
|
|
print_version() ;
|
|
|
|
exit(0) ;
|
|
|
|
}
|
2009-04-15 14:15:49 +02:00
|
|
|
}
|
2010-10-20 17:55:26 +02:00
|
|
|
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
2010-10-20 17:55:26 +02:00
|
|
|
// If -f isn't found, we use the default config file
|
|
|
|
if (config_file == NULL)
|
2009-04-15 14:15:49 +02:00
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
config_file =
|
|
|
|
malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ;
|
2009-04-15 14:15:49 +02:00
|
|
|
strcpy(config_file, DEFAULT_CONFIG_FILE) ;
|
|
|
|
}
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/* Parse config file */
|
|
|
|
cfg = cfg_init(opts, CFGF_NONE) ; // Initialise options
|
2009-08-04 12:02:52 +02:00
|
|
|
switch (cfg_parse(cfg, config_file))
|
2009-04-15 14:15:49 +02:00
|
|
|
{
|
2009-08-04 12:02:52 +02:00
|
|
|
case CFG_FILE_ERROR :
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr,
|
|
|
|
"Error! Cannot open configuration file « %s »: %s.\n",
|
|
|
|
config_file, strerror(errno)) ;
|
2009-08-04 12:02:52 +02:00
|
|
|
break ;
|
|
|
|
case CFG_PARSE_ERROR :
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr,
|
|
|
|
"Error! Parsing of configuration file « %s » failed!\n",
|
|
|
|
config_file) ;
|
2009-04-15 14:15:49 +02:00
|
|
|
free(config_file) ;
|
2010-07-13 14:39:03 +02:00
|
|
|
exit(ERR_PARSING_CONFIG_FILE) ;
|
2009-04-15 14:15:49 +02:00
|
|
|
}
|
|
|
|
free(config_file) ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_CONFIG_FILE
|
2010-07-13 15:09:07 +02:00
|
|
|
}
|
2009-07-02 09:42:15 +02:00
|
|
|
|
2009-04-15 14:15:49 +02:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
|
|
|
|
void parse_command_line(int argc, char **argv)
|
2011-04-06 18:11:14 +02:00
|
|
|
{
|
|
|
|
parse_main_options(argc, argv) ;
|
2011-06-24 15:38:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-04-06 18:11:14 +02:00
|
|
|
parse_calibration_data(argc, argv) ;
|
2011-06-24 15:38:07 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-04-06 18:11:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void parse_main_options(int argc, char **argv)
|
2010-07-13 15:09:07 +02:00
|
|
|
{
|
|
|
|
int opt ;
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
optind = 1 ; // Rewind argument parsing
|
2010-07-13 15:09:07 +02:00
|
|
|
|
2009-04-15 14:15:49 +02:00
|
|
|
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
2011-02-23 18:10:47 +01:00
|
|
|
{
|
2010-10-08 16:57:40 +02:00
|
|
|
case 'A' :
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
SET_AUTOCALIBRATION() ;
|
|
|
|
#else // USE_PTHREAD
|
2011-02-23 18:10:47 +01:00
|
|
|
fprintf(stderr, "Warning! The program was compiled without"
|
2010-10-08 16:57:40 +02:00
|
|
|
" support of POSIX threads, so -A (autocalibration)"
|
|
|
|
" is not available and will be ignored. All other"
|
|
|
|
" autocalibration-related options will also be"
|
|
|
|
" ignored.\n") ;
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
break ;
|
|
|
|
case 'a' :
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
SET_AUTOCALIBRATION_PORT(strtol(optarg, NULL, 0)) ;
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
break ;
|
2011-02-23 17:18:17 +01:00
|
|
|
case 'c' :
|
|
|
|
SET_DISPLAY_CAPTURED() ;
|
|
|
|
break ;
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'd' :
|
|
|
|
SET_AGGREGATION_IP(optarg) ;
|
|
|
|
break ;
|
2011-02-23 18:03:00 +01:00
|
|
|
case 'D' :
|
2011-06-24 15:38:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-02-23 18:03:00 +01:00
|
|
|
SET_AUTOCALIBRATION_IP(optarg) ;
|
2011-06-24 15:38:07 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-02-23 18:03:00 +01:00
|
|
|
break ;
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'f' : // Config file
|
|
|
|
break ; // (already parsed)
|
2010-10-20 17:55:26 +02:00
|
|
|
case 'h' : // Usage
|
|
|
|
break ; // (already parsed)
|
2010-10-08 16:57:40 +02:00
|
|
|
case 'H' :
|
2010-10-20 17:18:16 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2010-10-08 16:57:40 +02:00
|
|
|
SET_AUTOCALIBRATION_HELLO_DELAY(strtol(optarg, NULL, 0)) ;
|
2010-10-20 17:18:16 +02:00
|
|
|
#endif // USE_PTHREAD
|
2010-10-08 16:57:40 +02:00
|
|
|
break ;
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'k' :
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-02-23 18:10:47 +01:00
|
|
|
SET_KEEP_MONITOR() ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#else // USE_PTHREAD
|
2011-02-23 18:10:47 +01:00
|
|
|
fprintf(stderr, "Warning! The program was compiled without"
|
2010-07-13 14:39:03 +02:00
|
|
|
" support of POSIX threads, so -k (monitor mode"
|
|
|
|
" keeping-up) is not available and will be ignored."
|
|
|
|
"\n") ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-02-23 18:10:47 +01:00
|
|
|
break ;
|
|
|
|
case 'l' :
|
|
|
|
SET_LISTENING_PORT(strtol(optarg, NULL, 0)) ;
|
|
|
|
break ;
|
|
|
|
case 'm' :
|
2009-08-04 12:02:52 +02:00
|
|
|
SET_MODE(optarg[0]) ;
|
2011-02-23 18:10:47 +01:00
|
|
|
break ;
|
2010-10-12 10:13:59 +02:00
|
|
|
case 'n' :
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
SET_AUTOCALIBRATION_NBPKT(strtol(optarg, NULL, 0)) ;
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
break ;
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'p' :
|
|
|
|
SET_AGGREGATION_PORT(strtol(optarg, NULL, 0)) ;
|
|
|
|
break ;
|
2011-02-04 17:54:17 +01:00
|
|
|
case 'P' :
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
SET_AUTOCALIBRATION_REQUEST_PORT(strtol(optarg, NULL, 0)) ;
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
break ;
|
2009-08-04 12:02:52 +02:00
|
|
|
case 'q' :
|
2011-07-24 17:58:40 +02:00
|
|
|
RESET_VERBOSE() ;
|
2009-08-04 12:02:52 +02:00
|
|
|
break ;
|
2011-02-23 17:18:17 +01:00
|
|
|
case 'Q' :
|
|
|
|
UNSET_DISPLAY_CAPTURED() ;
|
|
|
|
break ;
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'r' :
|
|
|
|
SET_RTAP_IFACE(optarg) ;
|
|
|
|
break ;
|
2010-10-12 10:13:59 +02:00
|
|
|
case 't' :
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
SET_AUTOCALIBRATION_DELAY(strtol(optarg, NULL, 0)) ;
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
break ;
|
2009-08-04 12:02:52 +02:00
|
|
|
case 'v' :
|
2011-07-24 17:58:40 +02:00
|
|
|
INCREMENT_VERBOSE() ;
|
2009-08-04 12:02:52 +02:00
|
|
|
break ;
|
2010-10-20 17:55:26 +02:00
|
|
|
case 'V' : // Version
|
|
|
|
break ; // (already parsed)
|
2011-02-23 18:10:47 +01:00
|
|
|
case 'w' :
|
|
|
|
SET_WIFI_IFACE(optarg) ;
|
|
|
|
break ;
|
|
|
|
default :
|
|
|
|
print_usage() ;
|
|
|
|
exit(ERR_BAD_USAGE) ;
|
|
|
|
}
|
2009-04-15 14:15:49 +02:00
|
|
|
}
|
2010-07-13 15:09:07 +02:00
|
|
|
}
|
|
|
|
|
2009-04-15 14:15:49 +02:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
|
2011-06-24 15:38:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-04-06 18:11:14 +02:00
|
|
|
void parse_calibration_data(int argc, char **argv)
|
|
|
|
{
|
|
|
|
/* Parse remaining arguments (possible calibration data) */
|
|
|
|
if (argc - optind != 0)
|
|
|
|
{
|
|
|
|
if (argc - optind == 4)
|
|
|
|
{
|
|
|
|
coordinates_provided = TRUE ;
|
|
|
|
SET_MY_DIRECTION(strtoul(argv[optind++], NULL, 0)) ;
|
|
|
|
SET_MY_POSITION_X(strtod(argv[optind++], NULL)) ;
|
|
|
|
SET_MY_POSITION_Y(strtod(argv[optind++], NULL)) ;
|
|
|
|
SET_MY_POSITION_Z(strtod(argv[optind], NULL)) ;
|
|
|
|
}
|
|
|
|
else // Bad number of arguments
|
|
|
|
{
|
|
|
|
print_usage() ;
|
|
|
|
exit(ERR_BAD_USAGE) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-06-24 15:38:07 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-04-06 18:11:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
void check_configuration()
|
|
|
|
{
|
2009-08-04 12:02:52 +02:00
|
|
|
switch (GET_MODE())
|
|
|
|
{
|
|
|
|
case MODE_ACTIVE :
|
|
|
|
case MODE_MIXED :
|
|
|
|
case MODE_PASSIVE :
|
|
|
|
break ;
|
|
|
|
default :
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr, "Error! Unknown mode « %c ».\n", (char) GET_MODE()) ;
|
2010-07-13 15:09:07 +02:00
|
|
|
print_usage() ;
|
|
|
|
exit(ERR_BAD_USAGE) ;
|
2009-08-04 12:02:52 +02:00
|
|
|
}
|
2011-02-23 14:42:44 +01:00
|
|
|
|
2009-07-02 09:42:15 +02:00
|
|
|
if (GET_RTAP_IFACE()[0] == '\0')
|
2009-04-15 14:15:49 +02:00
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr, "Error! You must specify a radiotap interface"
|
|
|
|
" for the capture.\n") ;
|
2010-07-13 15:09:07 +02:00
|
|
|
print_usage() ;
|
|
|
|
exit(ERR_BAD_USAGE) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
2011-02-23 14:42:44 +01:00
|
|
|
|
2009-07-02 09:42:15 +02:00
|
|
|
if (GET_WIFI_IFACE()[0] == '\0')
|
2009-04-15 14:15:49 +02:00
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-02-23 14:42:44 +01:00
|
|
|
fprintf(stderr, "No Wi-Fi interface was specified. Failing back"
|
2011-02-23 18:10:47 +01:00
|
|
|
" to the radiotap interface (%s) instead.\n",
|
2011-02-23 14:42:44 +01:00
|
|
|
GET_RTAP_IFACE()) ;
|
2009-07-02 09:42:15 +02:00
|
|
|
SET_WIFI_IFACE(GET_RTAP_IFACE()) ;
|
2009-04-15 14:15:49 +02:00
|
|
|
}
|
2011-02-23 14:42:44 +01:00
|
|
|
|
2011-03-11 13:23:46 +01:00
|
|
|
// Port numbers //
|
|
|
|
if (GET_AGGREGATION_PORT() < 1 || GET_AGGREGATION_PORT() > 65535)
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-03-11 13:23:46 +01:00
|
|
|
fprintf(stderr, "Warning! Bad aggregation_port:"
|
|
|
|
" failing back to the default value.\n") ;
|
|
|
|
SET_AGGREGATION_PORT(AGGREGATE_DEFAULT_PORT) ;
|
|
|
|
}
|
|
|
|
if (GET_LISTENING_PORT() < 1 || GET_LISTENING_PORT() > 65535)
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-03-11 13:23:46 +01:00
|
|
|
fprintf(stderr, "Warning! Bad listening_port:"
|
|
|
|
" failing back to the default value.\n") ;
|
|
|
|
SET_LISTENING_PORT(LOC_REQUEST_DEFAULT_PORT) ;
|
|
|
|
}
|
2011-04-06 18:11:14 +02:00
|
|
|
|
|
|
|
// Autocalibration stuff //
|
2011-04-06 16:55:14 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-04-06 18:11:14 +02:00
|
|
|
if (GET_AUTOCALIBRATION())
|
2011-03-11 13:23:46 +01:00
|
|
|
{
|
2011-04-06 18:11:14 +02:00
|
|
|
if (GET_AUTOCALIBRATION_IP()[0] == '\0')
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-04-06 18:11:14 +02:00
|
|
|
fprintf(stderr, "No autocalibration IP specified, we will"
|
|
|
|
" use the aggregation IP as the destination of"
|
|
|
|
" autocalibration requests.\n") ;
|
|
|
|
SET_AUTOCALIBRATION_IP(GET_AGGREGATION_IP()) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GET_AUTOCALIBRATION_NBPKT() < 1)
|
|
|
|
fprintf(stderr, "Warning! autocalibration_nb_packets is null,"
|
|
|
|
" no autocalibration request will be sent!\n") ;
|
|
|
|
|
|
|
|
if (coordinates_provided)
|
|
|
|
if (GET_MY_DIRECTION() < OWL_DIRECTION_MIN ||
|
|
|
|
GET_MY_DIRECTION() > OWL_DIRECTION_MAX)
|
|
|
|
fprintf(stderr, "Warning! « %d » is not a valid"
|
|
|
|
" direction.\n", (int) GET_MY_DIRECTION()) ;
|
|
|
|
|
|
|
|
// Autocalibration port numbers
|
|
|
|
if (GET_AUTOCALIBRATION_REQUEST_PORT() < 1 ||
|
|
|
|
GET_AUTOCALIBRATION_REQUEST_PORT() > 65535)
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-04-06 18:11:14 +02:00
|
|
|
fprintf(stderr, "Warning! Bad autocalibration_request_port:"
|
|
|
|
" failing back to the default value.\n") ;
|
|
|
|
SET_AUTOCALIBRATION_REQUEST_PORT(DEFAULT_AUTOCALIBRATION_REQUEST_PORT) ;
|
|
|
|
}
|
|
|
|
if (GET_AUTOCALIBRATION_PORT() < 1 ||
|
|
|
|
GET_AUTOCALIBRATION_PORT() > 65535)
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-04-06 18:11:14 +02:00
|
|
|
fprintf(stderr, "Warning! Bad autocalibration_port:"
|
|
|
|
" failing back to the default value.\n") ;
|
|
|
|
SET_AUTOCALIBRATION_PORT(DEFAULT_AUTOCALIBRATION_PORT) ;
|
|
|
|
}
|
2011-03-11 13:23:46 +01:00
|
|
|
}
|
2011-04-06 16:55:14 +02:00
|
|
|
#endif // USE_PTHREAD
|
2010-07-13 15:09:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-15 14:15:49 +02:00
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
void print_configuration()
|
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr, "Configuration:\n") ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_CONFIG_FILE
|
2009-04-15 14:15:49 +02:00
|
|
|
cfg_print(cfg, stderr) ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#else // USE_CONFIG_FILE
|
2010-07-13 14:39:03 +02:00
|
|
|
fprintf(stderr,
|
2010-10-21 15:39:14 +02:00
|
|
|
"mode = %c\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"aggregation_ip = \"%s\"\n"
|
2011-03-10 19:18:43 +01:00
|
|
|
"aggregation_port = %"PRIuFAST16"\n"
|
|
|
|
"listening_port = %"PRIuFAST16"\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"rtap_iface = \"%s\"\n"
|
|
|
|
"wifi_iface = \"%s\"\n"
|
2010-10-21 15:39:14 +02:00
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
"keep_monitor = %s\n"
|
|
|
|
"autocalibration = %s\n"
|
2011-03-11 13:35:30 +01:00
|
|
|
"autocalibration_ip = \"%s\"\n"
|
2011-03-10 19:18:43 +01:00
|
|
|
"autocalibration_request_port = %"PRIuFAST16"\n"
|
|
|
|
"autocalibration_port = %"PRIuFAST16"\n"
|
|
|
|
"autocalibration_hello_delay = %"PRIuFAST32"\n"
|
|
|
|
"autocalibration_delay = %"PRIuFAST32"\n"
|
|
|
|
"autocalibration_nb_packets = %"PRIuFAST16"\n"
|
2011-04-06 18:11:14 +02:00
|
|
|
"my_direction = %"PRIu8"\n"
|
|
|
|
"my_position_x = %f\n"
|
|
|
|
"my_position_y = %f\n"
|
|
|
|
"my_position_z = %f\n"
|
2010-10-21 15:39:14 +02:00
|
|
|
#endif // USE_PTHREAD
|
|
|
|
"verbose = %s\n"
|
2011-02-23 17:18:17 +01:00
|
|
|
"display_captured = %s\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
,
|
2010-10-21 15:39:14 +02:00
|
|
|
GET_MODE(),
|
2011-02-23 18:03:00 +01:00
|
|
|
GET_AGGREGATION_IP(),
|
2011-02-23 18:10:47 +01:00
|
|
|
GET_AGGREGATION_PORT(),
|
|
|
|
GET_LISTENING_PORT(),
|
|
|
|
GET_RTAP_IFACE(),
|
2010-10-21 15:39:14 +02:00
|
|
|
GET_WIFI_IFACE(),
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-03-18 15:15:39 +01:00
|
|
|
OWL_BOOL_TO_STRING(GET_KEEP_MONITOR()),
|
|
|
|
OWL_BOOL_TO_STRING(GET_AUTOCALIBRATION()),
|
2011-02-23 18:03:00 +01:00
|
|
|
GET_AUTOCALIBRATION_IP(),
|
2011-02-04 17:54:17 +01:00
|
|
|
GET_AUTOCALIBRATION_REQUEST_PORT(),
|
2010-10-21 15:39:14 +02:00
|
|
|
GET_AUTOCALIBRATION_PORT(),
|
|
|
|
GET_AUTOCALIBRATION_HELLO_DELAY(),
|
|
|
|
GET_AUTOCALIBRATION_DELAY(),
|
|
|
|
GET_AUTOCALIBRATION_NBPKT(),
|
2011-04-06 18:11:14 +02:00
|
|
|
GET_MY_DIRECTION(),
|
|
|
|
GET_MY_POSITION_X(),
|
|
|
|
GET_MY_POSITION_Y(),
|
|
|
|
GET_MY_POSITION_Z(),
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_PTHREAD
|
2011-03-18 15:15:39 +01:00
|
|
|
OWL_BOOL_TO_STRING(GET_VERBOSE()),
|
|
|
|
OWL_BOOL_TO_STRING(GET_DISPLAY_CAPTURED())
|
2010-10-21 15:39:14 +02:00
|
|
|
) ;
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_CONFIG_FILE
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-07-02 09:42:15 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2010-07-13 14:39:03 +02:00
|
|
|
/*
|
|
|
|
* Thread function. Switches interface 'iface' to monitor mode every
|
|
|
|
* second.
|
|
|
|
*/
|
2011-03-24 08:30:54 +01:00
|
|
|
void* keep_mode_monitor(void *iface)
|
2008-02-27 17:37:08 +01:00
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-02-23 14:42:44 +01:00
|
|
|
fprintf(stderr, "Thread for keeping monitor mode launched.\n") ;
|
2010-10-08 16:57:40 +02:00
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
while (owl_run)
|
2008-02-27 17:37:08 +01:00
|
|
|
{
|
2011-03-11 11:19:44 +01:00
|
|
|
// Switch the interface to monitor mode:
|
2011-06-23 13:30:57 +02:00
|
|
|
iface_mode_monitor((char*) iface) ;
|
2010-07-13 14:39:03 +02:00
|
|
|
sleep(1) ; // Wait for 1 second
|
2008-02-27 17:37:08 +01:00
|
|
|
}
|
2011-03-24 08:30:54 +01:00
|
|
|
|
|
|
|
pthread_exit(NULL) ;
|
2008-02-27 17:37:08 +01:00
|
|
|
}
|
2011-06-23 13:30:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Switches the IEEE 802.11 interface 'iface' to Monitor mode.
|
|
|
|
*/
|
|
|
|
int iface_mode_monitor(const char *const iface)
|
|
|
|
{
|
|
|
|
struct iwreq wrq ;
|
|
|
|
int sockfd = iw_sockets_open() ;
|
|
|
|
|
|
|
|
strncpy((&wrq)->ifr_name, iface, IFNAMSIZ) ;
|
|
|
|
|
|
|
|
if (ioctl(sockfd, SIOCGIWMODE, &wrq) == -1) // Get current mode
|
|
|
|
{
|
|
|
|
perror("Error reading interface mode") ;
|
|
|
|
return ERR_READING_MODE ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If interface is not yet in Monitor mode
|
|
|
|
if (wrq.u.mode != IW_MODE_MONITOR)
|
|
|
|
{
|
|
|
|
wrq.u.mode = IW_MODE_MONITOR ;
|
|
|
|
if (ioctl(sockfd, SIOCSIWMODE, &wrq) == -1) // Set up Monitor mode
|
|
|
|
{
|
|
|
|
perror("Error setting up Monitor mode") ;
|
|
|
|
return ERR_SETTING_MODE ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close(sockfd) ;
|
|
|
|
|
|
|
|
return 0 ;
|
|
|
|
}
|
2009-07-02 09:42:15 +02:00
|
|
|
#endif // USE_PTHREAD
|
2008-02-27 17:37:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/*
|
|
|
|
* Captures packets using the radiotap interface.
|
|
|
|
* Captured data is transmitted to the aggregator.
|
2008-02-22 16:04:49 +01:00
|
|
|
*/
|
2009-08-04 12:02:52 +02:00
|
|
|
int capture()
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
char errbuf[PCAP_ERRBUF_SIZE] ; // Error message
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// Start capture:
|
2011-03-24 14:57:33 +01:00
|
|
|
capture_handler =
|
|
|
|
pcap_open_live(GET_RTAP_IFACE(), BUFSIZ, 1, 1000, errbuf) ;
|
|
|
|
if (capture_handler == NULL) // Capture starting failed
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2010-10-08 16:57:40 +02:00
|
|
|
fprintf(stderr, "Cannot open capture interface %s\n", errbuf) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
return ERR_OPENING_IFACE ;
|
|
|
|
}
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/* Open UDP socket to the aggregator */
|
2010-08-03 11:05:06 +02:00
|
|
|
aggregation_sockfd =
|
2011-03-11 10:36:59 +01:00
|
|
|
owlclient_create_trx_socket(GET_AGGREGATION_IP(),
|
|
|
|
GET_AGGREGATION_PORT(),
|
|
|
|
&aggregation_server, NULL) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
while (owl_run)
|
2010-08-03 11:05:06 +02:00
|
|
|
// Capture one packet at time, and call read_packet() on it:
|
2011-03-24 14:57:33 +01:00
|
|
|
pcap_loop(capture_handler, 1, read_packet, NULL) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-03-24 14:57:33 +01:00
|
|
|
pcap_close(capture_handler) ; // Stop capture
|
2011-03-24 08:43:43 +01:00
|
|
|
close(aggregation_sockfd) ; // Close socket
|
2008-02-14 08:54:51 +01:00
|
|
|
|
|
|
|
return 0 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/*
|
2010-08-03 11:05:06 +02:00
|
|
|
* Treats a packet and sends it to the aggregator.
|
2010-07-13 14:39:03 +02:00
|
|
|
*/
|
|
|
|
void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
2010-08-03 11:05:06 +02:00
|
|
|
const u_char *packet)
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2011-03-10 19:18:43 +01:00
|
|
|
uint16_t rtap_bytes ; // Received data size
|
|
|
|
uint32_t rtap_presentflags ;
|
|
|
|
uint_fast16_t rtap_position ;
|
2011-03-18 15:16:55 +01:00
|
|
|
owl_captured_request request ; // Message to send to the aggregator
|
2010-07-13 14:39:03 +02:00
|
|
|
ssize_t nsent ; // sendto return value
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool check[15] ; // Present flags
|
2011-03-10 19:18:43 +01:00
|
|
|
uint8_t raw_packet_fc1 ; // First byte of the received frame's FC
|
|
|
|
uint8_t raw_packet_fc2 ; // Second byte of the received frame's FC
|
|
|
|
uint8_t raw_packet_flags ; // IEEE 802.11 header flags
|
2011-02-03 18:21:51 +01:00
|
|
|
// Size of the IEEE 802.11 header:
|
2011-03-10 19:18:43 +01:00
|
|
|
uint_fast8_t ieee80211_header_size = IEEE80211_HEADER_SIZE_DATA ;
|
|
|
|
uint16_t llc_packet_type = 0 ;
|
2010-07-13 14:39:03 +02:00
|
|
|
// Pointer to the (possible) IP header of the packet:
|
|
|
|
struct iphdr *packet_ip_header = NULL ;
|
|
|
|
// Pointer to the (possible) UDP header of the packet:
|
|
|
|
struct udphdr *packet_udp_header = NULL ;
|
2010-11-23 19:00:24 +01:00
|
|
|
// Localisation request type (request, calibration, autocalibration):
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool is_explicit_packet = TRUE ; // Is the packet an explicit request?
|
2011-02-04 17:54:17 +01:00
|
|
|
// Is the packet an autocalibration positioning request?
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_bool uses_autocalibration_request_port = FALSE ;
|
2010-07-13 14:39:03 +02:00
|
|
|
int i ; // Iterator
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-05-03 13:44:08 +02:00
|
|
|
// Blank the request:
|
|
|
|
memset(&request, 0, sizeof(request)) ;
|
2009-09-03 18:43:38 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/* Common treatements */
|
2009-09-03 18:43:38 +02:00
|
|
|
|
2011-03-10 19:31:18 +01:00
|
|
|
// Copy 2 bytes from the 3rd packet byte, that is the size of the rtap
|
2010-07-13 14:39:03 +02:00
|
|
|
// header (changes with the flags):
|
2011-03-10 19:31:18 +01:00
|
|
|
memcpy(&rtap_bytes, &packet[2], sizeof(rtap_bytes)) ;
|
2010-11-19 19:23:10 +01:00
|
|
|
// Radiotap header is little-endian
|
|
|
|
rtap_bytes = le16toh(rtap_bytes) ;
|
2009-07-02 11:10:22 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// After the rtap header, there is the 802.11 header; the first byte
|
2011-01-24 12:02:35 +01:00
|
|
|
// is the first byte of the Frame Control (FC) field, which contains
|
|
|
|
// the type of the packet (Management, Control or Data) and its subtype
|
|
|
|
// (QoS, etc.):
|
2011-03-10 19:31:18 +01:00
|
|
|
raw_packet_fc1 = packet[rtap_bytes] ;
|
2011-02-03 18:21:51 +01:00
|
|
|
|
|
|
|
if (! IS_DATA_FRAME(raw_packet_fc1)) // Data frame?
|
2011-01-24 12:02:35 +01:00
|
|
|
goto not_explicit_packet ;
|
2009-07-02 11:10:22 +02:00
|
|
|
|
2011-02-03 18:21:51 +01:00
|
|
|
if (DATA_FRAME_IS_QOS(raw_packet_fc1)) // QoS Data frame?
|
|
|
|
ieee80211_header_size += 2 ; // 2 bytes of QoS information
|
|
|
|
|
2011-01-24 12:02:35 +01:00
|
|
|
// The second byte of the FC field contains the frame flags. The two
|
|
|
|
// first bits indicate the frame source and destination types: the
|
|
|
|
// first bit is "To DS" and the second is "From DS", so if the second
|
|
|
|
// bit is 0 the frame comes from a STA. That's what we want for an
|
|
|
|
// explicit packet:
|
2011-03-10 19:31:18 +01:00
|
|
|
raw_packet_fc2 = packet[rtap_bytes+1] ;
|
2011-02-03 18:21:51 +01:00
|
|
|
|
2011-01-24 12:02:35 +01:00
|
|
|
if (! IS_FRAME_FROM_STA(raw_packet_fc2))
|
2010-11-23 18:29:32 +01:00
|
|
|
goto not_explicit_packet ;
|
2009-09-03 18:43:38 +02:00
|
|
|
|
2010-11-23 18:29:32 +01:00
|
|
|
// Get the packet type (protocol, 2 bytes) from the LLC header:
|
2011-03-10 19:18:43 +01:00
|
|
|
memcpy(&llc_packet_type,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size + 6], 2) ;
|
2010-11-23 18:29:32 +01:00
|
|
|
llc_packet_type = ntohs(llc_packet_type) ;
|
2010-07-13 14:39:03 +02:00
|
|
|
|
2011-06-24 16:10:09 +02:00
|
|
|
if (llc_packet_type != ETHERTYPE_IP) // IP packet?
|
2010-11-23 18:29:32 +01:00
|
|
|
goto not_explicit_packet ;
|
|
|
|
|
|
|
|
packet_ip_header = (struct iphdr *)
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE] ;
|
2010-11-23 18:29:32 +01:00
|
|
|
// Get the source IP:
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(request.mobile_ip_addr_bytes, &packet_ip_header->saddr, 4) ;
|
2010-11-23 18:29:32 +01:00
|
|
|
|
|
|
|
if (GET_MODE() != MODE_PASSIVE) // If mode is active or mixed
|
2010-07-13 14:39:03 +02:00
|
|
|
{
|
2011-03-15 19:14:33 +01:00
|
|
|
uint_fast16_t dest_port ;
|
|
|
|
|
2010-11-23 18:29:32 +01:00
|
|
|
// Protocol for an explicit request is UDP
|
|
|
|
if (packet_ip_header->protocol != IPPROTO_UDP)
|
|
|
|
goto not_explicit_packet ;
|
|
|
|
|
|
|
|
// Check destination port:
|
|
|
|
packet_udp_header = (struct udphdr *)
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size +
|
|
|
|
LLC_HEADER_SIZE + sizeof(struct iphdr)] ;
|
2011-03-15 19:14:33 +01:00
|
|
|
dest_port = ntohs(packet_udp_header->dest) ;
|
2011-02-04 17:54:17 +01:00
|
|
|
|
2011-06-24 15:38:07 +02:00
|
|
|
#ifdef USE_PTHREAD
|
2011-03-15 19:14:33 +01:00
|
|
|
if (GET_AUTOCALIBRATION() && dest_port ==
|
|
|
|
(uint_fast16_t) GET_AUTOCALIBRATION_REQUEST_PORT())
|
2011-02-04 17:54:17 +01:00
|
|
|
uses_autocalibration_request_port = TRUE ;
|
2011-06-24 15:38:07 +02:00
|
|
|
else
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
if (dest_port != (uint_fast16_t) GET_LISTENING_PORT())
|
|
|
|
goto not_explicit_packet ;
|
2009-09-03 18:43:38 +02:00
|
|
|
}
|
2009-07-02 11:10:22 +02:00
|
|
|
|
2010-11-23 18:29:32 +01:00
|
|
|
goto process_packet ;
|
|
|
|
|
|
|
|
not_explicit_packet :
|
|
|
|
if (GET_MODE() == MODE_ACTIVE)
|
|
|
|
return ;
|
|
|
|
is_explicit_packet = FALSE ;
|
|
|
|
|
|
|
|
process_packet :
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// Get 802.11 flags from the 802.11 header:
|
2011-03-10 19:31:18 +01:00
|
|
|
raw_packet_flags = packet[rtap_bytes+1] ;
|
2008-03-14 11:31:04 +01:00
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (IS_RETRY(raw_packet_flags) && VERBOSE_CHATTERBOX)
|
2010-07-13 14:39:03 +02:00
|
|
|
printf("This packet is a Retry.\n") ;
|
2008-02-20 16:36:44 +01:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// Source MAC address is 10 bytes after the 802.11 packet type:
|
2011-03-24 23:42:42 +01:00
|
|
|
memcpy(request.mobile_mac_addr_bytes, &packet[rtap_bytes+10],
|
|
|
|
ETHER_ADDR_LEN) ;
|
2011-03-02 10:13:56 +01:00
|
|
|
|
|
|
|
// Drop the packet if it comes from the AP itself:
|
2011-03-18 15:16:55 +01:00
|
|
|
if (owl_mac_equals(my_mac_bytes, request.mobile_mac_addr_bytes))
|
2011-03-02 10:13:56 +01:00
|
|
|
return ;
|
|
|
|
|
2011-03-24 23:42:42 +01:00
|
|
|
// Copy AP MAC :
|
|
|
|
memcpy(request.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ;
|
2011-03-15 19:14:33 +01:00
|
|
|
// Capture time is in the pcap header (net-endian):
|
2011-03-18 15:16:55 +01:00
|
|
|
request.start_time = owl_timeval_to_timestamp(header->ts) ;
|
2009-09-03 11:09:48 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/* Active mode */
|
2009-09-03 18:43:38 +02:00
|
|
|
if (is_explicit_packet
|
|
|
|
&& (GET_MODE() == MODE_ACTIVE || GET_MODE() == MODE_MIXED)
|
2010-07-13 14:39:03 +02:00
|
|
|
// FIXME: should we really ignore Retries?
|
|
|
|
&& ! IS_RETRY(raw_packet_flags))
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2011-03-25 17:20:18 +01:00
|
|
|
request.type =
|
2011-03-10 19:31:18 +01:00
|
|
|
packet[rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE
|
|
|
|
+ sizeof(struct iphdr) + sizeof(struct udphdr)] ;
|
2011-03-25 17:20:18 +01:00
|
|
|
switch(request.type)
|
2011-02-23 18:10:47 +01:00
|
|
|
{
|
2011-03-25 16:30:40 +01:00
|
|
|
case OWL_REQUEST_NORMAL :
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-02-23 18:10:47 +01:00
|
|
|
printf("\nExplicit packet received.\n") ;
|
|
|
|
break ;
|
|
|
|
|
2011-03-25 16:30:40 +01:00
|
|
|
case OWL_REQUEST_CALIBRATION :
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-02-23 18:10:47 +01:00
|
|
|
printf("\nExplicit calibration packet received.\n") ;
|
2011-03-18 15:16:55 +01:00
|
|
|
request.direction =
|
2011-03-10 19:31:18 +01:00
|
|
|
packet[rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE
|
|
|
|
+ sizeof(struct iphdr) + sizeof(struct udphdr) + 9];
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(&request.x_position,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 10], sizeof(float)) ;
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(&request.y_position,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 14], sizeof(float)) ;
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(&request.z_position,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 18], sizeof(float)) ;
|
2011-02-23 18:10:47 +01:00
|
|
|
break ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-03-25 16:30:40 +01:00
|
|
|
case OWL_REQUEST_AUTOCALIBRATION :
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-02-04 17:54:17 +01:00
|
|
|
{
|
|
|
|
printf("\nAutocalibration packet received.") ;
|
2011-03-01 14:15:01 +01:00
|
|
|
if (! uses_autocalibration_request_port)
|
2011-02-04 17:54:17 +01:00
|
|
|
printf(".. on the wrong port!") ;
|
|
|
|
putchar('\n') ;
|
|
|
|
}
|
2011-04-06 18:11:14 +02:00
|
|
|
request.direction =
|
|
|
|
packet[rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE
|
|
|
|
+ sizeof(struct iphdr) + sizeof(struct udphdr) + 9];
|
|
|
|
memcpy(&request.x_position,
|
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 10], sizeof(float)) ;
|
|
|
|
memcpy(&request.y_position,
|
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 14], sizeof(float)) ;
|
|
|
|
memcpy(&request.z_position,
|
|
|
|
&packet[rtap_bytes + ieee80211_header_size
|
|
|
|
+ LLC_HEADER_SIZE + sizeof(struct iphdr)
|
|
|
|
+ sizeof(struct udphdr) + 18], sizeof(float)) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
break ;
|
|
|
|
|
2011-02-23 18:10:47 +01:00
|
|
|
default :
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-02-23 18:10:47 +01:00
|
|
|
printf("\nStrange explicit packet received\n") ;
|
|
|
|
fprintf(stderr,
|
2011-03-25 17:20:18 +01:00
|
|
|
"Error! Unknown request type (%d).\n", request.type) ;
|
2009-09-03 18:43:38 +02:00
|
|
|
is_explicit_packet = FALSE ;
|
2011-02-23 18:10:47 +01:00
|
|
|
}
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2009-09-03 18:43:38 +02:00
|
|
|
if (! is_explicit_packet)
|
2009-09-03 11:09:48 +02:00
|
|
|
{
|
|
|
|
if (GET_MODE() == MODE_ACTIVE)
|
|
|
|
return ;
|
2011-03-25 17:20:18 +01:00
|
|
|
else
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-03-25 17:20:18 +01:00
|
|
|
printf("\nThis strange explicit packet will be handled"
|
|
|
|
" as an implicit one.\n") ;
|
|
|
|
request.type = OWL_REQUEST_IMPLICIT ;
|
|
|
|
}
|
2009-09-03 11:09:48 +02:00
|
|
|
}
|
|
|
|
else
|
2011-03-15 19:14:33 +01:00
|
|
|
// Copy the timestamp "as is" (i.e. without changing endianess)
|
|
|
|
// because it will return to the network soon:
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(&request.request_time,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_bytes + ieee80211_header_size +
|
|
|
|
LLC_HEADER_SIZE + sizeof(struct iphdr) +
|
|
|
|
sizeof(struct udphdr) + 1],
|
2011-03-18 15:15:39 +01:00
|
|
|
sizeof(owl_timestamp)) ;
|
2009-09-03 11:09:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
else if (GET_MODE() == MODE_PASSIVE || GET_MODE() == MODE_MIXED)
|
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_CHATTERBOX)
|
2010-07-13 14:39:03 +02:00
|
|
|
printf("\nImplicit packet received.\n") ;
|
2011-03-25 17:20:18 +01:00
|
|
|
request.type = OWL_REQUEST_IMPLICIT ;
|
2009-09-03 11:09:48 +02:00
|
|
|
}
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
else // Active mode, packet was not an explicit request
|
2009-09-03 11:09:48 +02:00
|
|
|
return ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2009-09-03 18:43:38 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/* Radiotap header handling */
|
2009-09-03 18:43:38 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// Get rtap flags:
|
|
|
|
memcpy(&rtap_presentflags,
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ;
|
2010-11-19 19:23:10 +01:00
|
|
|
// Radiotap header is little-endian
|
2009-11-09 10:42:23 +01:00
|
|
|
rtap_presentflags = le32toh(rtap_presentflags) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
for (i = 0 ; i < 15 ; i++) // Initialise present flags structure
|
2009-09-03 11:09:48 +02:00
|
|
|
check[i] = FALSE ;
|
2010-07-13 14:39:03 +02:00
|
|
|
rtap_position = 8 ; // Begining of the present flags determined fields
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
// Test the first 15 bits of the flag field in order to check their
|
|
|
|
// presence and to copy them:
|
|
|
|
for (i = 0 ; i < 15 ; i++)
|
2009-09-03 11:09:48 +02:00
|
|
|
{
|
|
|
|
if ((rtap_presentflags % 2) == 1)
|
|
|
|
{
|
|
|
|
switch(i)
|
|
|
|
{
|
|
|
|
case RTAP_MACTS:
|
|
|
|
check[RTAP_MACTS] = TRUE ;
|
|
|
|
rtap_position += RTAP_L_MACTS ;
|
|
|
|
break ;
|
|
|
|
case RTAP_FLAGS:
|
|
|
|
check[RTAP_FLAGS] = TRUE;
|
|
|
|
rtap_position += RTAP_L_FLAGS ;
|
|
|
|
break ;
|
|
|
|
case RTAP_RATE:
|
|
|
|
check[RTAP_RATE] = TRUE;
|
|
|
|
rtap_position += RTAP_L_RATE ;
|
|
|
|
break ;
|
|
|
|
case RTAP_CHANNEL:
|
|
|
|
rtap_position += RTAP_L_CHANNEL ;
|
|
|
|
rtap_position += RTAP_L_CHANNELTYPE ;
|
|
|
|
break ;
|
|
|
|
case RTAP_FHSS:
|
|
|
|
check[RTAP_FHSS] = TRUE;
|
|
|
|
rtap_position += RTAP_L_FHSS ;
|
|
|
|
break ;
|
|
|
|
case RTAP_ANTENNASIGNALDBM:
|
2011-03-18 15:16:55 +01:00
|
|
|
memcpy(&(request.antenna_signal_dbm),
|
2011-03-10 19:31:18 +01:00
|
|
|
&packet[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
|
2009-09-03 11:09:48 +02:00
|
|
|
check[RTAP_ANTENNASIGNALDBM] = TRUE;
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2010-07-13 14:39:03 +02:00
|
|
|
printf("Antenna signal: %d dBm\n",
|
2011-03-18 15:16:55 +01:00
|
|
|
request.antenna_signal_dbm - 0x100);
|
2009-09-03 11:09:48 +02:00
|
|
|
rtap_position += RTAP_L_ANTENNASIGNALDBM ;
|
|
|
|
break ;
|
|
|
|
case RTAP_ANTENNANOISEDBM:
|
|
|
|
check[RTAP_ANTENNANOISEDBM] = TRUE;
|
|
|
|
rtap_position += RTAP_L_ANTENNANOISEDBM ;
|
|
|
|
break ;
|
|
|
|
case RTAP_LOCKQUALITY:
|
|
|
|
check[RTAP_LOCKQUALITY] = TRUE;
|
|
|
|
rtap_position += RTAP_L_LOCKQUALITY ;
|
|
|
|
break ;
|
|
|
|
case RTAP_TXATTENUATION:
|
|
|
|
check[RTAP_TXATTENUATION] = TRUE;
|
|
|
|
rtap_position += RTAP_L_TXATTENUATION ;
|
|
|
|
break ;
|
|
|
|
case RTAP_TXATTENUATIONDB:
|
|
|
|
check[RTAP_TXATTENUATIONDB] = TRUE;
|
|
|
|
rtap_position += RTAP_L_TXATTENUATIONDB ;
|
|
|
|
break ;
|
|
|
|
case RTAP_TXATTENUATIONDBM:
|
|
|
|
check[RTAP_TXATTENUATIONDBM] = TRUE;
|
|
|
|
rtap_position += RTAP_L_TXATTENUATIONDBM ;
|
|
|
|
break ;
|
|
|
|
case RTAP_ANTENNA:
|
|
|
|
check[RTAP_ANTENNA] = TRUE;
|
|
|
|
rtap_position += RTAP_L_ANTENNA ;
|
|
|
|
break ;
|
|
|
|
case RTAP_ANTENNASIGNALDB:
|
|
|
|
check[RTAP_ANTENNASIGNALDB] = TRUE;
|
|
|
|
rtap_position += RTAP_L_ANTENNASIGNALDB ;
|
|
|
|
break ;
|
|
|
|
case RTAP_ANTENNANOISEDB:
|
|
|
|
check[RTAP_ANTENNANOISEDB] = TRUE;
|
|
|
|
rtap_position += RTAP_L_ANTENNANOISEDB ;
|
|
|
|
break ;
|
|
|
|
case RTAP_FCS:
|
|
|
|
check[RTAP_FCS] = TRUE;
|
|
|
|
rtap_position += RTAP_L_FCS ;
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rtap_presentflags /= 2 ;
|
|
|
|
}
|
2008-02-14 08:54:51 +01:00
|
|
|
|
2011-02-23 17:18:17 +01:00
|
|
|
/* Display the packet details */
|
|
|
|
if (GET_DISPLAY_CAPTURED())
|
2009-09-03 11:09:48 +02:00
|
|
|
{
|
2011-03-15 16:16:26 +01:00
|
|
|
char
|
2011-03-18 15:15:39 +01:00
|
|
|
request_time_str[OWL_TIMESTAMP_STR_LEN],
|
|
|
|
start_time_str[OWL_TIMESTAMP_STR_LEN] ;
|
2011-03-15 19:14:33 +01:00
|
|
|
owl_timestamp_to_string(request_time_str,
|
2011-03-18 15:16:55 +01:00
|
|
|
owl_ntoh_timestamp(request.request_time)) ;
|
2011-03-15 19:14:33 +01:00
|
|
|
owl_timestamp_to_string(start_time_str,
|
2011-03-18 15:16:55 +01:00
|
|
|
owl_ntoh_timestamp(request.start_time)) ;
|
|
|
|
printf("*** Request to send ***\n"
|
2011-03-25 17:20:18 +01:00
|
|
|
"\tType: %"PRIu8"\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"\tMAC AP: %s\n"
|
|
|
|
"\tMobile MAC: %s\n"
|
2011-03-15 16:16:26 +01:00
|
|
|
"\tSequence number (request time): %s\n"
|
|
|
|
"\tRequest arrival time on the AP: %s\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"\tSignal: %d dBm\n"
|
|
|
|
"\tPosition X: %f\n"
|
|
|
|
"\tPosition Y: %f\n"
|
|
|
|
"\tPosition Z: %f\n"
|
|
|
|
"\tDirection: %hhd\n"
|
|
|
|
,
|
2011-03-25 17:20:18 +01:00
|
|
|
request.type,
|
2011-03-25 10:16:41 +01:00
|
|
|
owl_mac_bytes_to_string(request.ap_mac_addr_bytes),
|
|
|
|
owl_mac_bytes_to_string(request.mobile_mac_addr_bytes),
|
2011-03-15 16:16:26 +01:00
|
|
|
request_time_str,
|
|
|
|
start_time_str,
|
2011-05-03 13:38:50 +02:00
|
|
|
check[RTAP_ANTENNASIGNALDBM] ?
|
|
|
|
request.antenna_signal_dbm - 0x100 : 0,
|
2011-04-07 15:30:57 +02:00
|
|
|
owl_ntohf(request.x_position),
|
|
|
|
owl_ntohf(request.y_position),
|
|
|
|
owl_ntohf(request.z_position),
|
2011-03-18 15:16:55 +01:00
|
|
|
request.direction
|
2009-09-03 11:09:48 +02:00
|
|
|
) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
2009-08-04 12:02:52 +02:00
|
|
|
|
2011-03-18 15:16:55 +01:00
|
|
|
/* Send the request to the aggregator */
|
2010-07-13 14:39:03 +02:00
|
|
|
nsent =
|
2011-03-18 15:16:55 +01:00
|
|
|
sendto(aggregation_sockfd, &request, sizeof(request), 0,
|
2010-08-03 11:05:06 +02:00
|
|
|
(struct sockaddr *) &aggregation_server,
|
|
|
|
(socklen_t) sizeof(aggregation_server)) ;
|
2011-03-18 15:16:55 +01:00
|
|
|
if (nsent != (ssize_t) sizeof(request))
|
2009-08-04 12:02:52 +02:00
|
|
|
{
|
2011-03-18 15:16:55 +01:00
|
|
|
perror("Error sending request to the aggregation server") ;
|
2009-09-03 11:09:48 +02:00
|
|
|
return ;
|
2009-08-04 12:02:52 +02:00
|
|
|
}
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
/*
|
|
|
|
* Get our own MAC address and copy it to 'mac_bytes'.
|
|
|
|
*/
|
2011-03-24 23:42:42 +01:00
|
|
|
void get_mac_addr(char *eth, uint8_t mac_bytes[ETHER_ADDR_LEN])
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
|
|
|
int sockfd ;
|
|
|
|
|
2011-03-24 23:42:42 +01:00
|
|
|
// Empty mac_bytes:
|
|
|
|
memset(mac_bytes, 0, sizeof(uint8_t) * ETHER_ADDR_LEN) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
|
|
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
|
|
|
if(sockfd < 0)
|
2010-07-13 14:39:03 +02:00
|
|
|
perror("Cannot open socket to read MAC address") ;
|
2008-02-14 08:54:51 +01:00
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, eth, IFNAMSIZ) ;
|
|
|
|
|
|
|
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
|
|
|
return ;
|
|
|
|
|
|
|
|
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0)
|
|
|
|
return ;
|
|
|
|
|
2011-03-24 23:42:42 +01:00
|
|
|
memcpy(mac_bytes, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-13 17:42:00 +02:00
|
|
|
/*
|
|
|
|
* Get our own IP address and copy it to 'ip'.
|
|
|
|
*/
|
2011-03-24 08:40:35 +01:00
|
|
|
void get_ip_addr(char *eth, char ip[INET_ADDRSTRLEN])
|
2010-10-13 17:42:00 +02:00
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
|
|
|
int sockfd ;
|
|
|
|
struct sockaddr_in sa ;
|
2010-10-20 17:20:47 +02:00
|
|
|
struct in_addr ip_addr ;
|
2010-10-13 17:42:00 +02:00
|
|
|
|
|
|
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
|
|
|
|
if(sockfd < 0)
|
|
|
|
perror("Cannot open socket to read IP address") ;
|
|
|
|
|
|
|
|
strncpy(ifr.ifr_name, eth, IFNAMSIZ) ;
|
|
|
|
|
|
|
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
|
|
|
|
return ;
|
|
|
|
|
|
|
|
if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0)
|
|
|
|
return ;
|
|
|
|
|
2010-10-20 17:20:47 +02:00
|
|
|
memcpy(&ip_addr, &ifr.ifr_addr.sa_data[sizeof(sa.sin_port)],
|
|
|
|
sizeof(ip_addr)) ;
|
2011-03-24 08:40:35 +01:00
|
|
|
strncpy(ip, inet_ntoa(ip_addr), INET_ADDRSTRLEN) ;
|
2010-10-13 17:42:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-08 16:57:40 +02:00
|
|
|
/* *** Autocalibration functions *** */
|
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
|
2011-03-24 08:30:54 +01:00
|
|
|
void* autocalibrate_hello(void *NULL_value)
|
2010-10-08 16:57:40 +02:00
|
|
|
{
|
|
|
|
int send_sockfd ;
|
|
|
|
struct sockaddr_in serv;
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_autocalibration_hello message ;
|
2010-10-08 16:57:40 +02:00
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-02-23 14:42:44 +01:00
|
|
|
fprintf(stderr, "Autocalibration Hello thread launched.\n") ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2010-10-25 16:08:09 +02:00
|
|
|
send_sockfd =
|
2011-03-11 10:36:59 +01:00
|
|
|
owlclient_create_trx_socket(GET_AGGREGATION_IP(),
|
|
|
|
GET_AUTOCALIBRATION_PORT(),
|
|
|
|
&serv, NULL) ;
|
2011-03-24 10:38:01 +01:00
|
|
|
pthread_cleanup_push(&owl_close_fd, &send_sockfd) ;
|
2010-10-08 16:57:40 +02:00
|
|
|
|
2011-03-24 23:42:42 +01:00
|
|
|
memcpy(&message.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ;
|
2010-10-11 09:54:35 +02:00
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
while (owl_run)
|
2010-10-08 16:57:40 +02:00
|
|
|
{
|
2011-03-11 10:24:33 +01:00
|
|
|
owlclient_send_packet(send_sockfd, &serv,
|
|
|
|
&message, sizeof(message)) ;
|
2010-10-08 16:57:40 +02:00
|
|
|
sleep(GET_AUTOCALIBRATION_HELLO_DELAY()) ;
|
|
|
|
}
|
|
|
|
|
2011-03-24 10:38:01 +01:00
|
|
|
/* Close the socket */
|
|
|
|
pthread_cleanup_pop(1) ;
|
2011-03-24 08:30:54 +01:00
|
|
|
|
|
|
|
pthread_exit(NULL_value) ;
|
2010-10-08 16:57:40 +02:00
|
|
|
}
|
|
|
|
|
2010-10-12 10:13:59 +02:00
|
|
|
|
|
|
|
|
2011-03-24 08:30:54 +01:00
|
|
|
void* autocalibrate(void *NULL_value)
|
2010-10-12 10:13:59 +02:00
|
|
|
{
|
|
|
|
int nread ; // recvfrom return value
|
|
|
|
struct sockaddr_in client; // UDP client structure
|
|
|
|
socklen_t client_len = sizeof(client) ; // Size of clients
|
|
|
|
int listen_sockfd ;
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_autocalibration_order message ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_WARNING)
|
2011-02-23 14:42:44 +01:00
|
|
|
fprintf(stderr, "Autocalibration thread launched.\n") ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-02-04 17:54:17 +01:00
|
|
|
// Socket to send autocalibration positioning requests
|
2010-10-12 10:13:59 +02:00
|
|
|
autocalibration_send_sockfd =
|
2011-03-11 10:36:59 +01:00
|
|
|
owlclient_create_trx_socket(GET_AUTOCALIBRATION_IP(),
|
|
|
|
GET_AUTOCALIBRATION_REQUEST_PORT(),
|
|
|
|
&autocalibration_send_server,
|
|
|
|
GET_WIFI_IFACE()) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-02-04 17:54:17 +01:00
|
|
|
// Socket to receive orders from the aggregator
|
2010-10-12 10:13:59 +02:00
|
|
|
listen_sockfd =
|
2011-03-11 11:19:44 +01:00
|
|
|
owl_create_udp_listening_socket(GET_AUTOCALIBRATION_PORT()) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
if (listen_sockfd < 0)
|
|
|
|
{
|
|
|
|
perror("Error! Cannot create UDP listening socket from the"
|
|
|
|
" aggregation server") ;
|
|
|
|
exit(ERR_CREATING_SOCKET) ;
|
|
|
|
}
|
2011-03-24 10:38:01 +01:00
|
|
|
pthread_cleanup_push(&owl_close_fd, &listen_sockfd) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
while (owl_run)
|
2010-10-12 10:13:59 +02:00
|
|
|
{
|
|
|
|
nread = recvfrom(listen_sockfd, &message, sizeof(message), 0,
|
|
|
|
(struct sockaddr *) &client, &client_len) ;
|
|
|
|
|
2011-03-29 15:44:37 +02:00
|
|
|
if (nread <= 0 && owl_run)
|
2010-10-12 10:13:59 +02:00
|
|
|
{
|
2011-03-29 15:44:37 +02:00
|
|
|
if (owl_run)
|
2011-07-24 18:32:44 +02:00
|
|
|
perror("No message received from aggregator") ;
|
2010-10-12 10:13:59 +02:00
|
|
|
continue ;
|
|
|
|
}
|
|
|
|
|
2011-03-15 19:14:33 +01:00
|
|
|
if (message.order == AUTOCALIBRATION_ORDER_SEND)
|
2010-10-25 17:03:16 +02:00
|
|
|
{
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_INFO)
|
2011-02-23 14:42:44 +01:00
|
|
|
fprintf(stderr, "I was just ordered to send an"
|
|
|
|
" autocalibration request...\n") ;
|
2010-10-25 17:03:16 +02:00
|
|
|
send_autocalibration_request() ;
|
|
|
|
}
|
2010-10-12 10:13:59 +02:00
|
|
|
else
|
|
|
|
fprintf(stderr,
|
|
|
|
"Autocalibration order unknown: %d.\n", message.order) ;
|
|
|
|
}
|
|
|
|
|
2011-03-24 10:38:01 +01:00
|
|
|
/* Close the socket */
|
|
|
|
pthread_cleanup_pop(1) ;
|
2011-03-24 08:30:54 +01:00
|
|
|
|
|
|
|
pthread_exit(NULL_value) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void send_autocalibration_request()
|
|
|
|
{
|
2011-03-10 19:18:43 +01:00
|
|
|
uint8_t *packet ;
|
|
|
|
uint_fast16_t packet_size = make_packet(&packet) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-03-11 10:24:33 +01:00
|
|
|
owlclient_send_request(autocalibration_send_sockfd,
|
|
|
|
&autocalibration_send_server,
|
|
|
|
packet, packet_size,
|
|
|
|
GET_AUTOCALIBRATION_NBPKT(),
|
|
|
|
GET_AUTOCALIBRATION_DELAY()) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
|
|
|
free(packet) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates the calibration packet to send.
|
|
|
|
* The packet must be freed by the calling function.
|
|
|
|
* Returns the size of the packet.
|
|
|
|
*/
|
2011-03-10 19:18:43 +01:00
|
|
|
uint_fast16_t make_packet(uint8_t **packet)
|
2010-10-12 10:13:59 +02:00
|
|
|
{
|
2011-03-10 19:18:43 +01:00
|
|
|
uint8_t *pkt ;
|
|
|
|
uint_fast16_t size ; // Packet size
|
2011-04-06 18:11:14 +02:00
|
|
|
uint_fast16_t offset ; // Index used to create the packet
|
2011-03-18 15:15:39 +01:00
|
|
|
owl_timestamp request_time ;
|
2011-04-06 18:11:14 +02:00
|
|
|
float
|
2011-04-07 15:30:57 +02:00
|
|
|
my_position_x = owl_htonf(GET_MY_POSITION_X()),
|
|
|
|
my_position_y = owl_htonf(GET_MY_POSITION_Y()),
|
|
|
|
my_position_z = owl_htonf(GET_MY_POSITION_Z()) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-03-11 11:19:44 +01:00
|
|
|
owl_timestamp_now(&request_time) ;
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-07-24 18:32:06 +02:00
|
|
|
if (VERBOSE_CHATTERBOX)
|
2011-03-15 16:16:26 +01:00
|
|
|
{
|
2011-03-18 15:15:39 +01:00
|
|
|
char request_time_str[OWL_TIMESTAMP_STR_LEN] ;
|
2011-03-15 16:16:26 +01:00
|
|
|
owl_timestamp_to_string(request_time_str, request_time) ;
|
|
|
|
printf("Autocalibration time: %s\n", request_time_str) ;
|
|
|
|
}
|
2010-10-12 10:13:59 +02:00
|
|
|
|
2011-03-15 19:14:33 +01:00
|
|
|
request_time = owl_hton_timestamp(request_time) ;
|
|
|
|
|
2011-04-06 18:11:14 +02:00
|
|
|
offset = 0 ;
|
|
|
|
size =
|
|
|
|
sizeof(uint8_t) * 2 + sizeof(owl_timestamp) + sizeof(float) * 3 ;
|
2010-10-12 10:13:59 +02:00
|
|
|
pkt = malloc(size) ;
|
|
|
|
|
2011-04-06 18:11:14 +02:00
|
|
|
// Request type:
|
|
|
|
memset(&pkt[offset], OWL_REQUEST_AUTOCALIBRATION, 1) ;
|
|
|
|
++offset ;
|
|
|
|
// Timestamp:
|
|
|
|
memcpy(&pkt[offset], &request_time, sizeof(request_time)) ;
|
|
|
|
offset += sizeof(request_time) ;
|
|
|
|
// Coordinates:
|
|
|
|
pkt[offset] = GET_MY_DIRECTION() ;
|
|
|
|
++offset ;
|
|
|
|
memcpy(&pkt[offset], &my_position_x, sizeof(float)) ;
|
|
|
|
offset += sizeof(float) ;
|
|
|
|
memcpy(&pkt[offset], &my_position_y, sizeof(float)) ;
|
|
|
|
offset += sizeof(float) ;
|
|
|
|
memcpy(&pkt[offset], &my_position_z, sizeof(float)) ;
|
2011-07-24 18:58:21 +02:00
|
|
|
#ifndef NDEBUG
|
2011-04-06 18:11:14 +02:00
|
|
|
offset += sizeof(float) ;
|
|
|
|
assert(offset == size) ;
|
2011-07-24 18:58:21 +02:00
|
|
|
#endif // NDEBUG
|
2010-10-12 10:13:59 +02:00
|
|
|
|
|
|
|
*packet = pkt ;
|
|
|
|
return size ;
|
|
|
|
}
|
|
|
|
|
2010-10-08 16:57:40 +02:00
|
|
|
#endif // USE_PTHREAD
|
|
|
|
/* *** End of autocalibration functions *** */
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-03-24 14:57:33 +01:00
|
|
|
void sigint_handler(int num)
|
|
|
|
{
|
|
|
|
owl_sigint_handler(num) ;
|
|
|
|
pcap_breakloop(capture_handler) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sigterm_handler(int num)
|
|
|
|
{
|
|
|
|
owl_sigterm_handler(num) ;
|
|
|
|
pcap_breakloop(capture_handler) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-07-13 15:09:07 +02:00
|
|
|
void print_usage()
|
2008-02-14 08:54:51 +01:00
|
|
|
{
|
2010-07-13 14:39:03 +02:00
|
|
|
printf("Usage :\n"
|
|
|
|
"\t%s [-f config_file] [-m mode] [-d aggregation_ip]"
|
|
|
|
" [-l listening_port] [-p aggregation_port] -r rtap_iface"
|
2011-07-24 18:32:06 +02:00
|
|
|
" [-w wifi_iface] [-k] [-v[v[v]] | -q] [-c | -Q] [-A]"
|
2011-02-23 18:03:00 +01:00
|
|
|
" [-D autocalibration_ip]"
|
2011-02-23 17:32:04 +01:00
|
|
|
" [-P autocalibration_request_port ] [-a autocalibration_port]"
|
2010-10-12 10:13:59 +02:00
|
|
|
" [-H autocalibration_hello_delay] [-t autocalibration_delay]"
|
2011-04-06 18:11:14 +02:00
|
|
|
" [-n autocalibration_nb_packets] [direction x y z]\n"
|
2010-10-20 17:55:26 +02:00
|
|
|
"\t%s -h\n"
|
|
|
|
"\t%s -V\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
|
|
|
|
"Main options:\n"
|
2010-07-13 14:42:33 +02:00
|
|
|
"\t-h\t\tPrint this help.\n"
|
2011-04-12 22:03:08 +02:00
|
|
|
"\t-V\t\tShow version information.\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"\t-f config_file\tUse 'config_file' instead of the default"
|
|
|
|
" configuration file (%s). Available only if program was"
|
|
|
|
" compiled with libconfuse.\n"
|
|
|
|
|
|
|
|
"Capture options:\n"
|
|
|
|
"\t-m mode\t\t\tCapture mode: a(ctive), p(assive), m(ixed)"
|
|
|
|
" (default: a).\n"
|
2010-10-08 16:57:40 +02:00
|
|
|
"\t-l listening_port\tPort on which explicit positioning"
|
|
|
|
" requests are sent by mobiles (default: %d).\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"\t-d aggregation_ip\tIP address of the aggregation server"
|
|
|
|
" (default: 127.0.0.1)\n"
|
2010-10-08 16:57:40 +02:00
|
|
|
"\t-p aggregation_port\tRequests are transmitted to the"
|
|
|
|
" aggregation server on this port (default: %d).\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
"\t-r rtap_iface\t\tRadiotap capture interface.\n"
|
|
|
|
"\t-w wifi_iface\t\tPhysical interface behind rtap_iface"
|
|
|
|
" (default: rtap_iface).\n"
|
|
|
|
|
2010-10-08 16:57:40 +02:00
|
|
|
"Autocalibration options:\n"
|
|
|
|
"(These options are available only if the program was compiled"
|
|
|
|
" with support of POSIX threads.)\n"
|
2011-02-23 17:32:04 +01:00
|
|
|
"\t-A\t\t\tEnable autocalibration (default: disabled).\n"
|
2011-02-23 18:03:00 +01:00
|
|
|
"\t-D autocalib_ip\t\tDestination IP of the autocalibration"
|
|
|
|
"requests (default: aggregation_ip).\n"
|
2011-04-06 18:11:14 +02:00
|
|
|
"\t-P autocalib_req_port\tPort on which autocalibration"
|
|
|
|
" positioning requests are sent (default: %d).\n"
|
|
|
|
"\t-a autocalib_port\tPort on which autocalibration data (hello"
|
|
|
|
" & orders) are exchanged with the aggregation server"
|
|
|
|
" (default: %d).\n"
|
2011-07-24 20:08:05 +02:00
|
|
|
"\t-H hello_delay\t\tTime between each hello message sent to"
|
|
|
|
" the aggregation server, in seconds (default: %d s).\n"
|
2011-02-23 17:32:04 +01:00
|
|
|
"\t-t delay\t\tTime between each autocalibration"
|
2011-07-24 20:08:05 +02:00
|
|
|
" packet transmission, in milliseconds (default: %d ms).\n"
|
2011-02-23 17:32:04 +01:00
|
|
|
"\t-n nb_packets\t\tNumber of packet transmitted"
|
2010-10-12 10:13:59 +02:00
|
|
|
" for one autocalibration request (default: %d).\n"
|
2011-04-06 18:11:14 +02:00
|
|
|
"\tdirection x y z\t\tThe coordinates of the listener"
|
|
|
|
" (direction is an integer; x, y, z are floats).\n"
|
2010-10-08 16:57:40 +02:00
|
|
|
|
2010-07-13 14:39:03 +02:00
|
|
|
"Other options:\n"
|
|
|
|
"\t-k\tKeep the monitor mode up on wifi_iface. Use it with buggy"
|
|
|
|
" drivers that disable monitor mode periodically. Available"
|
|
|
|
" only if the program was compiled with support of POSIX"
|
|
|
|
" threads.\n"
|
2011-07-24 18:32:06 +02:00
|
|
|
"\t-v\tBe verbose. You can use this option up to 3 times to"
|
|
|
|
" increase the level of verbosity (1 = warnings, 2 = useful"
|
|
|
|
" information, 3 = a lot of information.\n"
|
|
|
|
"\t-q\tQuiet mode (default): sets the verbose level to 0.\n"
|
|
|
|
"\t-c\tDisplay the captured packets.\n"
|
|
|
|
"\t-Q\tDo not display the captured packets (default).\n"
|
2010-07-13 14:39:03 +02:00
|
|
|
,
|
2010-07-13 15:09:07 +02:00
|
|
|
program_name,
|
2010-10-20 17:55:26 +02:00
|
|
|
program_name,
|
|
|
|
program_name,
|
2010-07-13 14:39:03 +02:00
|
|
|
DEFAULT_CONFIG_FILE,
|
2010-10-08 16:57:40 +02:00
|
|
|
LOC_REQUEST_DEFAULT_PORT,
|
|
|
|
AGGREGATE_DEFAULT_PORT,
|
2011-02-04 17:54:17 +01:00
|
|
|
DEFAULT_AUTOCALIBRATION_REQUEST_PORT,
|
2010-10-14 18:30:41 +02:00
|
|
|
DEFAULT_AUTOCALIBRATION_PORT,
|
|
|
|
DEFAULT_AUTOCALIBRATION_HELLO_DELAY,
|
|
|
|
DEFAULT_AUTOCALIBRATION_DELAY,
|
|
|
|
DEFAULT_AUTOCALIBRATION_NBPKT
|
2009-08-04 12:02:52 +02:00
|
|
|
) ;
|
2008-02-14 08:54:51 +01:00
|
|
|
}
|
2010-10-20 17:55:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
void print_version()
|
|
|
|
{
|
2011-04-12 22:03:08 +02:00
|
|
|
printf("This is OwlPS Listener, part of the Open Wireless Positioning"
|
2010-10-20 17:55:26 +02:00
|
|
|
" System project.\n"
|
2011-04-12 22:03:08 +02:00
|
|
|
"Version: %s.\n"
|
2010-10-20 17:55:26 +02:00
|
|
|
"Compilation-time options:\n"
|
|
|
|
"\tSupport for POSIX threads: %s.\n"
|
|
|
|
"\tSupport for configuration file (libconfuse): %s.\n",
|
2011-04-12 22:03:08 +02:00
|
|
|
#ifdef OWLPS_VERSION
|
|
|
|
OWLPS_VERSION
|
|
|
|
#else // OWLPS_VERSION
|
|
|
|
"unknown version"
|
|
|
|
#endif // OWLPS_VERSION
|
|
|
|
,
|
2010-10-20 17:55:26 +02:00
|
|
|
#ifdef USE_PTHREAD
|
|
|
|
"YES"
|
|
|
|
#else // USE_PTHREAD
|
|
|
|
"NO"
|
|
|
|
#endif // USE_PTHREAD
|
|
|
|
,
|
|
|
|
#ifdef USE_CONFIG_FILE
|
|
|
|
"YES"
|
|
|
|
#else // USE_CONFIG_FILE
|
|
|
|
"NO"
|
|
|
|
#endif // USE_CONFIG_FILE
|
|
|
|
) ;
|
|
|
|
}
|