Merge branch 'dev' into dev-drone

- Fix send calibration message.
- Update makefile to add version.
This commit is contained in:
Florian Taillard 2011-04-13 11:12:08 +02:00 committed by Matteo Cypriani
commit e45c199130
40 changed files with 780 additions and 344 deletions

26
TODO
View File

@ -4,8 +4,11 @@
- Use string for network exchanges?
- Mark arguments as const in function headers if needed
That is done in the owlps-positioning C++ code, but not constantly
in C modules.
- Allow to use hostnames instead of IP addresses.
in C modules. [Done in libowlps & libowlps-client.]
- Allow to use hostnames instead of IP addresses in all modules
getaddrinfo(3) (or gethostbyname(3)) should be used when opening
sockets in libowlps, then string buffer size have to be adapted in
all modules to be able to contain a long hostname.
- Use struct ether_addr to store MAC addresses?
We could use the struct ether_addr to store binary MAC addresses,
and convert them to strings with ether_ntoa() instead of
@ -14,14 +17,18 @@
* libowlps
- Delete timestamp_is_null()?
This function is currently not used.
- Currently unused functions:
° owl_timestamp_is_null()
° owl_iface_channel_hop()
° owl_iface_set_channel() (except by owl_iface_channel_hop())
- Move owl_iface_mode_monitor() in owlps-listenerd.c.
* Aggregator
- inet_ntoa() is not secure with threads
Use inet_ntop() instead?
(But it is currently used by only one thread.) Use inet_ntop()
instead?
- Use locks to read/write the AP list
Currently, several threads can access the list simultaneously, and
that's not cool!
@ -34,17 +41,14 @@
request. We should define an option to allow user to choose the
time he wants.
- Allow blank parameters for output options.
- Fix segfault on SIGINT.
* Listener
- Send coordinates in autocalibration requests
The listener should be able to know its own position and transmit
it in autocalibration requests.
- Refactor and review read_packet().
- Listen for autocalibration requests without sending requests?
- read_packet(): use ieee80211_header_size for all implicit packets
Currently the size is corrected only for data packets.
- Fix segfault when rtap_iface is not in monitor mode (?) on Foneras.
- Move endianess #defines in libowlps?
- Merge Makefile and Makefile_atheros?
Use autohell?
@ -55,7 +59,7 @@
* Client
- Allow to use a string for the direction
- Allow to use a string for the direction?
Could be nice, but probably useless.

View File

@ -16,9 +16,10 @@
* 'iface' if specified (if you want the interface to be selected,
* automatically, this parameter should be NULL or an empty string).
*/
int owlclient_create_trx_socket(char *dest_ip, uint_fast16_t dest_port,
struct sockaddr_in *server,
char *iface)
int owlclient_create_trx_socket(const char *const dest_ip,
const uint_fast16_t dest_port,
struct sockaddr_in *const server,
const char *const iface)
{
struct sockaddr_in client ;
@ -41,7 +42,7 @@ int owlclient_create_trx_socket(char *dest_ip, uint_fast16_t dest_port,
/* Selects 'iface' as sending interface for the socket 'sockfd'. */
void owlclient_use_iface(int sockfd, char *iface)
void owlclient_use_iface(const int sockfd, const char *const iface)
{
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface,
strlen(iface) + 1) == -1)
@ -55,12 +56,18 @@ void owlclient_use_iface(int sockfd, char *iface)
void owlclient_send_request(int sockfd, struct sockaddr_in *server,
void *packet, uint_fast16_t packet_size,
uint_fast16_t nb_pkt, uint_fast32_t delay)
void owlclient_send_request(const int sockfd,
const struct sockaddr_in *const server,
const void *const packet,
const uint_fast16_t packet_size,
const uint_fast16_t nb_pkt,
const uint_fast32_t delay)
{
uint_fast16_t i ;
if (nb_pkt == 0)
return ;
#ifdef DEBUG
printf("Sent packets: ") ;
#endif // DEBUG
@ -82,8 +89,10 @@ void owlclient_send_request(int sockfd, struct sockaddr_in *server,
void owlclient_send_packet(int sockfd, struct sockaddr_in *server,
void *packet, uint_fast16_t packet_size)
void owlclient_send_packet(const int sockfd,
const struct sockaddr_in *const server,
const void *const packet,
const uint_fast16_t packet_size)
{
ssize_t nsent = sendto(sockfd, packet, packet_size, 0,
(struct sockaddr *) server,

View File

@ -14,15 +14,21 @@
/* Function headers */
int owlclient_create_trx_socket(char *dest_ip, uint_fast16_t dest_port,
struct sockaddr_in *server,
char *iface) ;
void owlclient_use_iface(int sockfd, char *iface) ;
void owlclient_send_request(int sockfd, struct sockaddr_in *server,
void *packet, uint_fast16_t packet_size,
uint_fast16_t nb_pkt, uint_fast32_t delay) ;
void owlclient_send_packet(int sockfd, struct sockaddr_in *server,
void *packet, uint_fast16_t packet_size) ;
int owlclient_create_trx_socket(const char *const dest_ip,
const uint_fast16_t dest_port,
struct sockaddr_in *const server,
const char *const iface) ;
void owlclient_use_iface(const int sockfd, const char *const iface) ;
void owlclient_send_request(const int sockfd,
const struct sockaddr_in *const server,
const void *const packet,
const uint_fast16_t packet_size,
const uint_fast16_t nb_pkt,
const uint_fast32_t delay) ;
void owlclient_send_packet(const int sockfd,
const struct sockaddr_in *const server,
const void *const packet,
const uint_fast16_t packet_size) ;
#endif // _LIBOWLPS_CLIENT_

View File

@ -17,6 +17,8 @@
#include <net/if.h>
#include <iwlib.h>
#include <assert.h>
#define DEBUG
@ -24,13 +26,16 @@ owl_bool owl_run = TRUE ;
/* *** Miscellaneous functions *** */
/*
* Converts a MAC address from bytes to string.
* The string is allocated in a static buffer, and will be overwritten
* each time this function is called.
* This function is not thread-safe!
*/
const char* owl_mac_bytes_to_string(uint8_t *mac_binary)
const char* owl_mac_bytes_to_string(const uint8_t *const mac_binary)
{
static char mac_str[OWL_ETHER_ADDR_STRLEN] ;
owl_mac_bytes_to_string_r(mac_binary, mac_str) ;
@ -38,13 +43,12 @@ const char* owl_mac_bytes_to_string(uint8_t *mac_binary)
}
/*
* Converts a MAC address from bytes to string.
* 'mac_str' must be allocated by the caller.
* This function is thread-safe.
*/
void owl_mac_bytes_to_string_r(uint8_t *mac_binary,
void owl_mac_bytes_to_string_r(const uint8_t *const mac_binary,
char mac_str[OWL_ETHER_ADDR_STRLEN])
{
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
@ -53,12 +57,26 @@ void owl_mac_bytes_to_string_r(uint8_t *mac_binary,
}
/*
* Compares two MAC addresses.
* Returns TRUE if they are identical, FALSE otherwise.
*/
owl_bool owl_mac_equals(const uint8_t *const mac1,
const uint8_t *const mac2)
{
int i ;
for (i = 0 ; i < ETHER_ADDR_LEN ; ++i)
if(mac1[i] != mac2[i])
return FALSE ;
return TRUE ;
}
/*
* Converts a IEEE 802.11 frequency into a channel number.
* Returns 0 if the frequency does not correspond to an official channel.
*/
uint_fast8_t owl_frequency_to_channel(uint_fast16_t channel)
uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel)
{
uint_fast8_t c = 0 ; // Result
@ -113,11 +131,14 @@ uint_fast8_t owl_frequency_to_channel(uint_fast16_t channel)
/* *** Time *** */
/*
* Sets the owl_timestamp 'now' at the current time.
* Returns 0 in case of success non-zero otherwise.
*/
int owl_timestamp_now(owl_timestamp *now)
int owl_timestamp_now(owl_timestamp *const now)
{
int ret ;
struct timespec now_ts ;
@ -133,7 +154,6 @@ int owl_timestamp_now(owl_timestamp *now)
}
/*
* Returns a owl_timestamp from a struct timespec.
*/
@ -146,7 +166,6 @@ owl_timestamp owl_timespec_to_timestamp(const struct timespec d)
}
/*
* Returns a owl_timestamp from a struct timeval.
*/
@ -159,44 +178,40 @@ owl_timestamp owl_timeval_to_timestamp(const struct timeval d)
}
owl_bool owl_timestamp_equals(owl_timestamp d1, owl_timestamp d2)
owl_bool owl_timestamp_equals(const owl_timestamp d1,
const owl_timestamp d2)
{
return d1.tv_sec == d2.tv_sec && d1.tv_nsec == d2.tv_nsec ;
}
owl_bool owl_timestamp_is_null(owl_timestamp d)
owl_bool owl_timestamp_is_null(const owl_timestamp d)
{
return d.tv_sec == 0 && d.tv_nsec == 0 ;
}
/*
* Converts a owl_timestamp date value into milliseconds.
*/
uint64_t owl_timestamp_to_ms(owl_timestamp d)
uint64_t owl_timestamp_to_ms(const owl_timestamp d)
{
return (uint64_t) d.tv_sec * 1000u + (uint64_t) d.tv_nsec / 1000000lu ;
}
/*
* Converts a owl_timestamp date value into a printable string.
* 'dst' must be an allocated array of at least owl_timestamp_STR_LEN
* characters.
*/
void owl_timestamp_to_string(char *dst, owl_timestamp src)
void owl_timestamp_to_string(char *const dst, const owl_timestamp src)
{
snprintf(dst, OWL_TIMESTAMP_STR_LEN, "%"PRIu32".%"PRIu32,
src.tv_sec, src.tv_nsec) ;
}
/*
* Returns the time (in milliseconds) between two dates.
*/
@ -207,7 +222,6 @@ uint_fast32_t owl_time_elapsed_ms(const owl_timestamp d1,
}
/*
* Returns a owl_timestamp storing the time between two dates.
*/
@ -226,47 +240,60 @@ owl_timestamp owl_time_elapsed(const owl_timestamp d1,
/* *** Endianess *** */
/*
* Converts a owl_timestamp from host endianess to network endianess.
*/
owl_timestamp owl_hton_timestamp(owl_timestamp date)
owl_timestamp owl_hton_timestamp(const owl_timestamp d)
{
owl_timestamp d ;
d.tv_sec = htonl(date.tv_sec) ;
d.tv_nsec = htonl(date.tv_nsec) ;
return d ;
owl_timestamp date ;
date.tv_sec = htonl(d.tv_sec) ;
date.tv_nsec = htonl(d.tv_nsec) ;
return date ;
}
/*
* Converts a owl_timestamp from network endianess to host endianess.
*/
owl_timestamp owl_ntoh_timestamp(owl_timestamp date)
owl_timestamp owl_ntoh_timestamp(const owl_timestamp d)
{
owl_timestamp d ;
d.tv_sec = ntohl(date.tv_sec) ;
d.tv_nsec = ntohl(date.tv_nsec) ;
return d ;
owl_timestamp date ;
date.tv_sec = ntohl(d.tv_sec) ;
date.tv_nsec = ntohl(d.tv_nsec) ;
return date ;
}
/*
* Compares two MAC addresses.
* Returns TRUE if they are identical, FALSE otherwise.
* Swap bytes composing a float.
* You probably want to use the macros owl_htonf() and owl_ntohf()
* instead of this function.
*/
owl_bool owl_mac_equals(uint8_t *mac1, uint8_t *mac2)
float owl_swap_float(const float f)
{
int i ;
for (i = 0 ; i < ETHER_ADDR_LEN ; ++i)
if(mac1[i] != mac2[i])
return FALSE ;
return TRUE ;
float ret ;
char
*f_bytes = (char*) &f,
*ret_bytes = (char*) &ret ;
assert(sizeof(float) == 4) ;
ret_bytes[0] = f_bytes[3] ;
ret_bytes[1] = f_bytes[2] ;
ret_bytes[2] = f_bytes[1] ;
ret_bytes[3] = f_bytes[0] ;
return ret ;
}
/* *** Network *** */
/*
* Creates a UDP transmission socket and returns its descriptor.
* Parameters:
@ -277,14 +304,14 @@ owl_bool owl_mac_equals(uint8_t *mac1, uint8_t *mac2)
* - client_description (in/out): the structure in which the client
* description will be saved.
*/
int owl_create_udp_trx_socket(char *server_address,
uint_fast16_t server_port,
struct sockaddr_in *server_description,
struct sockaddr_in *client_description)
int owl_create_udp_trx_socket(const char *const server_address,
const uint_fast16_t server_port,
struct sockaddr_in *const server_description,
struct sockaddr_in *const client_description)
{
int sockfd ; // Socket descriptor
/* Ceate the UDP socket */
/* Create the UDP socket */
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
if (sockfd < 0)
{
@ -309,13 +336,12 @@ int owl_create_udp_trx_socket(char *server_address,
}
/*
* Creates a UDP reception socket and returns its descriptor.
* Parameters:
* - port: port on which the socket listens.
*/
int owl_create_udp_listening_socket(uint_fast16_t port)
int owl_create_udp_listening_socket(const uint_fast16_t port)
{
int sockfd ; // Socket descriptor
struct sockaddr_in server_description ; // Server structure
@ -350,11 +376,10 @@ int owl_create_udp_listening_socket(uint_fast16_t port)
}
/*
* Switches the IEEE 802.11 interface 'iface' to Monitor mode.
*/
int owl_iface_mode_monitor(char *iface)
int owl_iface_mode_monitor(const char *const iface)
{
struct iwreq wrq ;
int sockfd = iw_sockets_open() ;
@ -384,12 +409,12 @@ int owl_iface_mode_monitor(char *iface)
}
/*
* Sets the IEEE 802.11 channel of the interface 'iface'.
* 'channel' must be an integer between 1 and 14.
*/
int owl_iface_set_channel(char *iface, uint_fast8_t channel)
int owl_iface_set_channel(const char *const iface,
const uint_fast8_t channel)
{
struct iwreq wrq ;
int sockfd = iw_sockets_open() ;
@ -410,12 +435,11 @@ int owl_iface_set_channel(char *iface, uint_fast8_t channel)
}
/*
* Switches alternatively the Wi-Fi channel of the IEEE 802.11 interface
* 'iface' to 4 or 11.
*/
int owl_iface_channel_hop(char *iface)
int owl_iface_channel_hop(const char *const iface)
{
uint_fast16_t channel ;
struct iwreq wrq ;
@ -425,7 +449,7 @@ int owl_iface_channel_hop(char *iface)
if (ioctl(sockfd, SIOCGIWFREQ, &wrq) == -1)
{
perror("Erreur lors de la lecture de la fréquence ") ;
perror("Error reading the frequency") ;
return ERR_READING_CHANNEL ;
}
// The following is not very clean: we should use iw_freq2float(),
@ -447,10 +471,13 @@ int owl_iface_channel_hop(char *iface)
/* *** Signals *** */
/*
* Generic signal handler for SIGINT.
*/
void owl_sigint_handler(int num)
void owl_sigint_handler(const int num)
{
if (num != SIGINT)
{
@ -468,9 +495,10 @@ void owl_sigint_handler(int num)
}
/* Gestionnaire de signal générique pour SIGTERM */
void owl_sigterm_handler(int num)
/*
* Generic signal handler for SIGTERM.
*/
void owl_sigterm_handler(const int num)
{
if (num != SIGTERM)
{
@ -484,16 +512,19 @@ void owl_sigterm_handler(int num)
/* *** Thread-related functions *** */
/*
* Closes the file descriptor 'fd'.
* 'fd' must be passed as an int pointer (int*).
*/
void owl_close_fd(void *fd)
void owl_close_fd(void *const fd)
{
if (fd == NULL)
return ;
int *file_desc = fd ;
const int *const file_desc = fd ;
if (close(*file_desc) != 0)
perror("Error closing file descriptor") ;
#ifdef DEBUG
@ -504,13 +535,12 @@ void owl_close_fd(void *fd)
}
/*
* Closes the stream 'file'.
* 'file' must be passed as a pointer on a pointer of FILE (FILE**).
* If *file either stdout, stderr or stdin, it will not be closed.
*/
void owl_close_file(void *file)
void owl_close_file(void *const file)
{
if (file == NULL)
return ;

View File

@ -232,44 +232,59 @@ extern owl_bool owl_run ;
/* Function headers */
// Misc
const char* owl_mac_bytes_to_string(uint8_t *mac_binary) ;
void owl_mac_bytes_to_string_r(uint8_t *mac_binary,
const char* owl_mac_bytes_to_string(const uint8_t *const mac_binary) ;
void owl_mac_bytes_to_string_r(const uint8_t *const mac_binary,
char mac_str[OWL_ETHER_ADDR_STRLEN]) ;
owl_bool owl_mac_equals(uint8_t *mac1, uint8_t *mac2) ;
uint_fast8_t owl_frequency_to_channel(uint_fast16_t channel) ;
owl_bool owl_mac_equals(const uint8_t *const mac1,
const uint8_t *const mac2) ;
uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel) ;
// Time
int owl_timestamp_now(owl_timestamp *now) ;
int owl_timestamp_now(owl_timestamp *const now) ;
owl_timestamp owl_timespec_to_timestamp(const struct timespec d) ;
owl_timestamp owl_timeval_to_timestamp(const struct timeval d) ;
void owl_timestamp_to_string(char *dst, owl_timestamp src) ;
owl_bool owl_timestamp_equals(owl_timestamp d1, owl_timestamp d2) ;
owl_bool owl_timestamp_is_null(owl_timestamp d) ;
uint64_t owl_timestamp_to_ms(owl_timestamp date) ;
owl_bool owl_timestamp_equals(const owl_timestamp d1,
const owl_timestamp d2) ;
owl_bool owl_timestamp_is_null(const owl_timestamp d) ;
uint64_t owl_timestamp_to_ms(const owl_timestamp d) ;
void owl_timestamp_to_string(char *const dst, const owl_timestamp src) ;
uint_fast32_t owl_time_elapsed_ms(const owl_timestamp d1,
const owl_timestamp d2) ;
owl_timestamp owl_time_elapsed(const owl_timestamp d1,
const owl_timestamp d2) ;
owl_timestamp owl_hton_timestamp(owl_timestamp date) ;
owl_timestamp owl_ntoh_timestamp(owl_timestamp date) ;
// Endianess
owl_timestamp owl_hton_timestamp(const owl_timestamp d) ;
owl_timestamp owl_ntoh_timestamp(const owl_timestamp d) ;
float owl_swap_float(const float f) ;
#if __BYTE_ORDER == __BIG_ENDIAN
# define owl_htonf(f) (f)
# define owl_ntohf(f) (f)
#else // __BYTE_ORDER == __BIG_ENDIAN
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define owl_htonf(f) owl_swap_float(f)
# define owl_ntohf(f) owl_swap_float(f)
# endif // __BYTE_ORDER == __LITTLE_ENDIAN
#endif // __BYTE_ORDER == __BIG_ENDIAN
// Network
int owl_create_udp_trx_socket(char *server_address,
uint_fast16_t server_port,
struct sockaddr_in *server_description,
struct sockaddr_in *client_description) ;
int owl_create_udp_listening_socket(uint_fast16_t port) ;
int owl_iface_mode_monitor(char *iface) ;
int owl_iface_set_channel(char *iface, uint_fast8_t channel) ;
int owl_iface_channel_hop(char *iface) ;
int owl_create_udp_trx_socket(const char *const server_address,
const uint_fast16_t server_port,
struct sockaddr_in *const server_description,
struct sockaddr_in *const client_description) ;
int owl_create_udp_listening_socket(const uint_fast16_t port) ;
int owl_iface_mode_monitor(const char *const iface) ;
int owl_iface_set_channel(const char *const iface,
const uint_fast8_t channel) ;
int owl_iface_channel_hop(const char *const iface) ;
// Signals
void owl_sigint_handler(int num) ;
void owl_sigterm_handler(int num) ;
void owl_sigint_handler(const int num) ;
void owl_sigterm_handler(const int num) ;
// Threads
void owl_close_fd(void *fd) ;
void owl_close_file(void *file) ;
void owl_close_fd(void *const fd) ;
void owl_close_file(void *const file) ;
/* Macros */

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Répertoire d'installation
PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/bin
@ -25,7 +30,7 @@ CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR)
DEPFLAGS=-MMD
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG=-fPIC
#OWLPSFLAGS =
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
LIBS = -pthread -lconfuse -L$(LIBOWLPS_DIR) -lowlps
LDFLAGS = $(LIBS) $(OWLPSFLAGS)

View File

@ -11,7 +11,7 @@
/* Arguments & program configuration */
#define OPTIONS "Aa:c:C:f:hi:k:K:l:o:p:t:v" // getopt string
#define OPTIONS "Aa:c:C:f:hi:k:K:l:o:p:t:vV" // getopt string
#define DEFAULT_CONFIG_FILE "/usr/local/etc/owlps/owlps-aggregator.conf"
#define DEFAULT_AGGREGATE_TIMEOUT 1500 // milliseconds
#define DEFAULT_KEEP_TIMEOUT 3000 // milliseconds
@ -112,5 +112,6 @@ void order_send(ap_list *ap) ;
void free_ap_list(void) ;
void print_usage(void) ;
void print_version(void) ;
#endif // _OWLPS_AGGREGATOR_H_

View File

@ -188,19 +188,30 @@ void parse_config_file(int argc, char **argv)
CFG_END()
} ;
char *config_file ;
char *config_file = NULL ; // Configuration file name
// Option -f specifies a config file, so we search for it first
// Option -f specifies a config file, options -h and -V exit the
// program, so we search for them first
int opt ;
do
opt = getopt(argc, argv, OPTIONS) ;
while (opt != 'f' && opt != -1) ;
if (opt == 'f')
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ;
strcpy(config_file, optarg) ;
switch (opt)
{
case 'f' :
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ;
strcpy(config_file, optarg) ;
break ;
case 'h' :
print_usage() ;
exit(0) ;
case 'V' :
print_version() ;
exit(0) ;
}
}
else // If -f isn't found, we use the default config file
// If -f isn't found, we use the default config file
if (config_file == NULL)
{
config_file =
malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ;
@ -415,6 +426,9 @@ int read_loop(int sockfd)
// Endianess conversions:
request.request_time = owl_ntoh_timestamp(request.request_time) ;
request.start_time = owl_ntoh_timestamp(request.start_time) ;
request.x_position = owl_ntohf(request.x_position) ;
request.y_position = owl_ntohf(request.y_position) ;
request.z_position = owl_ntohf(request.z_position) ;
if (cfg_getbool(cfg, "verbose"))
{
@ -436,7 +450,7 @@ int read_loop(int sockfd)
"\tPosition X: %f\n"
"\tPosition Y: %f\n"
"\tPosition Z: %f\n"
"\tDirection: %hhd\n"
"\tDirection: %"PRIu8"\n"
,
request.type,
owl_mac_bytes_to_string(request.ap_mac_addr_bytes),
@ -1228,9 +1242,12 @@ void print_usage()
" [-K ap_keep_timeout]"
" [-C ap_check_interval]"
"\n"
"\t%s -h\n"
"\t%s -V\n"
"Main options:\n"
"\t-h\t\tPrint this help.\n"
"\t-V\t\tShow version information.\n"
"\t-f config_file\tUse 'config_file' instead of the default"
" configuration file (%s).\n"
"\t-v\t\tBe verbose (print detailed info on each received"
@ -1249,7 +1266,7 @@ void print_usage()
" treated (default: %d).\n"
"\t-t aggregate_timeout\tRequests are stored during"
" 'aggregate_timeout' milliseconds before to be grouped"
" (default: %d ms).\n"
" (default: %d ms).\n"
"\t-k keep_timeout\t\tAggregated requests are kept during"
" 'keep_timeout' milliseconds (default: %d ms).\n"
"\t-c check_interval\tTime between two checks of the stored"
@ -1265,6 +1282,8 @@ void print_usage()
" checks of the stored APs (default: %d ms).\n"
,
program_name,
program_name,
program_name,
DEFAULT_CONFIG_FILE,
POSITIONER_DEFAULT_IP,
POSITIONER_DEFAULT_PORT,
@ -1277,3 +1296,17 @@ void print_usage()
DEFAULT_AP_CHECK_INTERVAL
) ;
}
void print_version()
{
printf("This is OwlPS Aggregator, part of the Open Wireless"
" Positioning System project.\n"
"Version: %s.\n",
#ifdef OWLPS_VERSION
OWLPS_VERSION
#else // OWLPS_VERSION
"unknown version"
#endif // OWLPS_VERSION
) ;
}

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Répertoire d'installation
PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/bin
@ -29,7 +34,7 @@ XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC
LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client
STATIC_LIBS = -liw -lm -lrt
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ##
@ -42,7 +47,7 @@ all : dynamic static
% : %.o
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
%.o : %.c $(HEADER)
$(CC) $(XCFLAGS) -c $<
$(CC) $(XCFLAGS) $(OWLPSFLAGS) -c $<
# Compilation du programme
$(TARGET) : $(TARGET).o $(HEADER)

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = /arm
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/bin
@ -39,7 +44,7 @@ STATIC_LIBS = $(LOWLPSA) $(LIBS)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ##
@ -56,7 +61,7 @@ all: semistatic static
# $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(DYNAMIC_LIBS)
%: %.o
$(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(SEMISTATIC_LIBS)
$(CC) $(STRIPFLAGS) $(XCFLAGS) $(OWLPSFLAGS) -o $@ $^ $(LDFLAGS) $(SEMISTATIC_LIBS)
%.static: %.o
$(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(STATIC_LIBS) \

View File

@ -146,6 +146,9 @@ void parse_main_options(int argc, char **argv)
case 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
case 'V' :
print_version() ;
exit(0) ;
default :
print_usage() ;
exit(ERR_BAD_USAGE) ;
@ -219,7 +222,7 @@ void check_configuration()
else
options.nb_pkt = DEFAULT_NBPKT_NORMAL ;
}
// Calibration request but bad direction
if (is_calibration_request)
if (options.direction < OWL_DIRECTION_MIN ||
@ -271,7 +274,7 @@ void print_configuration()
"\tDelay: %"PRIuFAST32"\n"
"\tNumber of packets: %"PRIuFAST16"\n"
"\tListening port: %"PRIuFAST16"\n"
"\tDirection: %d\n"
"\tDirection: %"PRIu8"\n"
"\tX: %f\n"
"\tY: %f\n"
"\tZ: %f\n"
@ -341,6 +344,9 @@ void make_packet()
printf("Direction = %d, X = %f, Y = %f, Z = %f\n",
packet[offset - 1], options.x, options.y, options.z) ;
#endif // DEBUG
options.x = owl_htonf(options.x) ;
options.y = owl_htonf(options.y) ;
options.z = owl_htonf(options.z) ;
memcpy(&packet[offset], &options.x, sizeof(float)) ;
offset += sizeof(float) ;
memcpy(&packet[offset], &options.y, sizeof(float)) ;
@ -546,6 +552,7 @@ void print_usage()
"\n"
"Options:\n"
"\t-h\t\tPrint this help.\n"
"\t-V\t\tPrint version information.\n"
"\t-d dest_ip\tDestination IP address of the localisation request.\n"
"\t-p dest_port\tDestination port of the localisation request"
" (default: %d).\n"
@ -572,3 +579,17 @@ void print_usage()
MOBILE_DEFAULT_PORT
) ;
}
void print_version()
{
printf("This is OwlPS Client for AR.Drone, part of the Open Wireless"
" Positioning System project.\n"
"Version: %s.\n",
#ifdef OWLPS_VERSION
OWLPS_VERSION
#else // OWLPS_VERSION
"unknown version"
#endif // OWLPS_VERSION:w
) ;
}

View File

@ -16,7 +16,7 @@
#define DEFAULT_DELAY_NORMAL 25000 // Localisation request
/* Program arguments (getopt string) */
#define OPTIONS "d:hi:l::n:p:t:"
#define OPTIONS "d:hi:l::n:p:t:V"
/* Function headers */
@ -37,6 +37,7 @@ void send_labview(char*) ;
void string2data(char*) ;
void* thread_send(void*) ;
void print_error(char*) ;
void print_version(void) ;
typedef struct result result;
/* Struct */

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Répertoire d'installation
PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/bin
@ -27,6 +32,7 @@ CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \
DEPFLAGS = -MMD
XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client
STATIC_LIBS = -liw -lm -lrt
@ -42,7 +48,7 @@ all : dynamic static
% : %.o
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
%.o : %.c $(HEADER)
$(CC) $(XCFLAGS) -c $<
$(CC) $(XCFLAGS) $(OWLPSFLAGS) -c $<
# Compilation du programme
$(TARGET) : $(TARGET).o $(HEADER)

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/staging_dir/toolchain-mips_gcc4.1.2/bin
@ -40,6 +45,7 @@ STATIC_LIBS = $(LOWLPSA) $(LIBS)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ##

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/10.03
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/staging_dir/toolchain-mips_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/bin
@ -40,6 +45,7 @@ STATIC_LIBS = $(LOWLPSA) $(LIBS)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ##

View File

@ -26,7 +26,7 @@
#define DEFAULT_DELAY_NORMAL 25000 // Localisation request
/* Program arguments (getopt string) */
#define OPTIONS "d:hi:l::n:p:t:"
#define OPTIONS "d:hi:l::n:p:t:V"
/* Function headers */
@ -43,6 +43,7 @@ void make_packet(void) ;
void send_request(void) ;
void receive_position(void) ;
void print_usage(void) ;
void print_version(void) ;
/* Options */
@ -162,6 +163,9 @@ void parse_main_options(int argc, char **argv)
case 't' :
options.delay = strtol(optarg, NULL, 0) ;
break ;
case 'V' :
print_version() ;
exit(0) ;
default :
print_usage() ;
exit(ERR_BAD_USAGE) ;
@ -287,7 +291,7 @@ void print_configuration()
"\tDelay: %"PRIuFAST32"\n"
"\tNumber of packets: %"PRIuFAST16"\n"
"\tListening port: %"PRIuFAST16"\n"
"\tDirection: %d\n"
"\tDirection: %"PRIu8"\n"
"\tX: %f\n"
"\tY: %f\n"
"\tZ: %f\n"
@ -348,6 +352,9 @@ void make_packet()
printf("Direction = %d, X = %f, Y = %f, Z = %f\n",
packet[offset - 1], options.x, options.y, options.z) ;
#endif // DEBUG
options.x = owl_htonf(options.x) ;
options.y = owl_htonf(options.y) ;
options.z = owl_htonf(options.z) ;
memcpy(&packet[offset], &options.x, sizeof(float)) ;
offset += sizeof(float) ;
memcpy(&packet[offset], &options.y, sizeof(float)) ;
@ -405,6 +412,7 @@ void print_usage()
"\n"
"Options:\n"
"\t-h\t\tPrint this help.\n"
"\t-V\t\tPrint version information.\n"
"\t-d dest_ip\tDestination IP address of the localisation request.\n"
"\t-p dest_port\tDestination port of the localisation request"
" (default: %d).\n"
@ -431,3 +439,17 @@ void print_usage()
MOBILE_DEFAULT_PORT
) ;
}
void print_version()
{
printf("This is OwlPS Client, part of the Open Wireless"
" Positioning System project.\n"
"Version: %s.\n",
#ifdef OWLPS_VERSION
OWLPS_VERSION
#else // OWLPS_VERSION
"unknown version"
#endif // OWLPS_VERSION
) ;
}

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Répertoire d'installation
PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/sbin
@ -27,7 +32,8 @@ CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \
DEPFLAGS = -MMD
XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC
OWLPSFLAGS = -D USE_CONFIG_FILE -lconfuse -D USE_PTHREAD -pthread
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" \
-D USE_CONFIG_FILE -lconfuse -D USE_PTHREAD -pthread
LIBS = -L$(LIBOWLPS_DIR) -lowlps \
-L$(LIBOWLPSCLIENT_DIR) -lowlps-client \
-lpcap

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe)
endif
# Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/staging_dir/toolchain-mips_gcc4.1.2/bin
@ -36,7 +41,8 @@ LOWLPSCLIENTA = $(LIBOWLPSCLIENT_DIR)/libowlps-client.a
LIBS = -lpcap -liw -lm $(LOWLPSCLIENTA)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
OWLPSFLAGS = -D USE_PTHREAD -pthread
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" \
-D USE_PTHREAD -pthread
#OWLPSFLAGS += -D USE_CONFIG_FILE -lconfuse
LDFLAGS = $(OWLPSFLAGS) $(LIBS)

View File

@ -24,23 +24,25 @@
* version of glibc, or another libc (e.g. uClibc), we must define them
* manually.
*/
#ifndef le32toh
# if __BYTE_ORDER == __LITTLE_ENDIAN
#if __BYTE_ORDER == __LITTLE_ENDIAN
# ifndef le32toh
# define le32toh(x) (x)
# else // __BYTE_ORDER == __LITTLE_ENDIAN
# include <byteswap.h>
# define le32toh(x) bswap_32(x)
# endif // __BYTE_ORDER == __LITTLE_ENDIAN
#endif // le32toh
#ifndef le16toh
# if __BYTE_ORDER == __LITTLE_ENDIAN
# endif // le32toh
# ifndef le16toh
# define le16toh(x) (x)
# else // __BYTE_ORDER == __LITTLE_ENDIAN
# include <byteswap.h>
# define le16toh(x) bswap_16(x)
# endif // __BYTE_ORDER == __LITTLE_ENDIAN
#endif // le16toh
# endif // le16toh
#else // __BYTE_ORDER == __LITTLE_ENDIAN
# if __BYTE_ORDER == __BIG_ENDIAN
# ifndef le32toh
# include <byteswap.h>
# define le32toh(x) bswap_32(x)
# endif // le32toh
# ifndef le16toh
# include <byteswap.h>
# define le16toh(x) bswap_16(x)
# endif // le16toh
# endif // __BYTE_ORDER == __BIG_ENDIAN
#endif // __BYTE_ORDER == __LITTLE_ENDIAN
/* Arguments & program configuration */
@ -63,6 +65,8 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ;
void initialise_configuration(int argc, char **argv) ;
void parse_config_file(int argc, char **argv) ;
void parse_command_line(int argc, char **argv) ;
void parse_main_options(int argc, char **argv) ;
void parse_calibration_data(int argc, char **argv) ;
void check_configuration(void) ;
#ifdef DEBUG
void print_configuration(void) ;
@ -157,6 +161,22 @@ void print_version(void) ;
(cfg_setint(cfg, "autocalibration_nb_packets", (NBPKT)))
#define GET_AUTOCALIBRATION_NBPKT() \
(cfg_getint(cfg, "autocalibration_nb_packets"))
#define SET_MY_DIRECTION(DIRECTION) \
(cfg_setint(cfg, "my_direction", (DIRECTION)))
#define GET_MY_DIRECTION() \
(cfg_getint(cfg, "my_direction"))
#define SET_MY_POSITION_X(POSITION) \
(cfg_setfloat(cfg, "my_position_x", (POSITION)))
#define GET_MY_POSITION_X() \
(cfg_getfloat(cfg, "my_position_x"))
#define SET_MY_POSITION_Y(POSITION) \
(cfg_setfloat(cfg, "my_position_y", (POSITION)))
#define GET_MY_POSITION_Y() \
(cfg_getfloat(cfg, "my_position_y"))
#define SET_MY_POSITION_Z(POSITION) \
(cfg_setfloat(cfg, "my_position_z", (POSITION)))
#define GET_MY_POSITION_Z() \
(cfg_getfloat(cfg, "my_position_z"))
#endif // USE_PTHREAD
#define SET_VERBOSE() \
@ -234,6 +254,22 @@ void print_version(void) ;
(options.autocalibration_nb_packets = (NBPKT))
#define GET_AUTOCALIBRATION_NBPKT() \
(options.autocalibration_nb_packets)
#define SET_MY_DIRECTION(DIRECTION) \
(options.my_direction = (DIRECTION))
#define GET_MY_DIRECTION() \
(options.my_direction)
#define SET_MY_POSITION_X(POSITION) \
(options.my_position_x = (POSITION))
#define GET_MY_POSITION_X() \
(options.my_position_x)
#define SET_MY_POSITION_Y(POSITION) \
(options.my_position_y = (POSITION))
#define GET_MY_POSITION_Y() \
(options.my_position_y)
#define SET_MY_POSITION_Z(POSITION) \
(options.my_position_z = (POSITION))
#define GET_MY_POSITION_Z() \
(options.my_position_z)
#endif // USE_PTHREAD
#define SET_VERBOSE() \

View File

@ -28,6 +28,8 @@
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <assert.h>
char *program_name = NULL ;
uint8_t my_mac_bytes[ETHER_ADDR_LEN] ; // AP MAC address
@ -36,8 +38,13 @@ char my_ip[INET_ADDRSTRLEN] ; // AP IP address
pcap_t *capture_handler = NULL ; // Packet capture descriptor
int aggregation_sockfd ;
struct sockaddr_in aggregation_server ;
#ifdef USE_PTHREAD
int autocalibration_send_sockfd ;
struct sockaddr_in autocalibration_send_server ;
// TRUE if the coordinates of the listener were provided by the user:
owl_bool coordinates_provided = FALSE ;
#endif // USE_PTHREAD
#ifdef USE_CONFIG_FILE
cfg_t *cfg ; // Configuration structure
@ -64,6 +71,10 @@ struct {
uint_fast32_t autocalibration_hello_delay ;
uint_fast32_t autocalibration_delay ;
uint_fast16_t autocalibration_nb_packets ;
owl_direction my_direction ;
float my_position_x ;
float my_position_y ;
float my_position_z ;
#endif // USE_PTHREAD
owl_bool verbose ;
owl_bool display_captured ;
@ -85,6 +96,7 @@ struct {
DEFAULT_AUTOCALIBRATION_HELLO_DELAY,
DEFAULT_AUTOCALIBRATION_DELAY,
DEFAULT_AUTOCALIBRATION_NBPKT,
0, 0, 0, 0,
#endif // USE_PTHREAD
FALSE,
FALSE
@ -278,6 +290,14 @@ void parse_config_file(int argc, char **argv)
// Number of packets for a calibration request:
CFG_INT("autocalibration_nb_packets",
DEFAULT_AUTOCALIBRATION_NBPKT, CFGF_NONE),
// 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),
#endif // USE_PTHREAD
// Be verbose, or not:
CFG_BOOL("verbose", cfg_false, CFGF_NONE),
@ -306,6 +326,7 @@ void parse_config_file(int argc, char **argv)
" You must specify all options on the command line,"
" or default value will be used.\n") ;
#endif // USE_CONFIG_FILE
break ;
case 'h' :
print_usage() ;
exit(0) ;
@ -347,6 +368,14 @@ void parse_config_file(int argc, char **argv)
void parse_command_line(int argc, char **argv)
{
parse_main_options(argc, argv) ;
parse_calibration_data(argc, argv) ;
}
void parse_main_options(int argc, char **argv)
{
int opt ;
@ -450,6 +479,29 @@ void parse_command_line(int argc, char **argv)
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) ;
}
}
}
void check_configuration()
{
switch (GET_MODE())
@ -481,15 +533,6 @@ void check_configuration()
SET_WIFI_IFACE(GET_RTAP_IFACE()) ;
}
if (GET_AUTOCALIBRATION() && GET_AUTOCALIBRATION_IP()[0] == '\0')
{
if (GET_VERBOSE())
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()) ;
}
// Port numbers //
if (GET_AGGREGATION_PORT() < 1 || GET_AGGREGATION_PORT() > 65535)
{
@ -505,22 +548,49 @@ void check_configuration()
" failing back to the default value.\n") ;
SET_LISTENING_PORT(LOC_REQUEST_DEFAULT_PORT) ;
}
if (GET_AUTOCALIBRATION_REQUEST_PORT() < 1 ||
GET_AUTOCALIBRATION_REQUEST_PORT() > 65535)
// Autocalibration stuff //
#ifdef USE_PTHREAD
if (GET_AUTOCALIBRATION())
{
if (GET_VERBOSE())
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)
{
if (GET_VERBOSE())
fprintf(stderr, "Warning! Bad autocalibration_port:"
" failing back to the default value.\n") ;
SET_AUTOCALIBRATION_PORT(DEFAULT_AUTOCALIBRATION_PORT) ;
if (GET_AUTOCALIBRATION_IP()[0] == '\0')
{
if (GET_VERBOSE())
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)
{
if (GET_VERBOSE())
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)
{
if (GET_VERBOSE())
fprintf(stderr, "Warning! Bad autocalibration_port:"
" failing back to the default value.\n") ;
SET_AUTOCALIBRATION_PORT(DEFAULT_AUTOCALIBRATION_PORT) ;
}
}
#endif // USE_PTHREAD
}
@ -548,6 +618,10 @@ void print_configuration()
"autocalibration_hello_delay = %"PRIuFAST32"\n"
"autocalibration_delay = %"PRIuFAST32"\n"
"autocalibration_nb_packets = %"PRIuFAST16"\n"
"my_direction = %"PRIu8"\n"
"my_position_x = %f\n"
"my_position_y = %f\n"
"my_position_z = %f\n"
#endif // USE_PTHREAD
"verbose = %s\n"
"display_captured = %s\n"
@ -567,6 +641,10 @@ void print_configuration()
GET_AUTOCALIBRATION_HELLO_DELAY(),
GET_AUTOCALIBRATION_DELAY(),
GET_AUTOCALIBRATION_NBPKT(),
GET_MY_DIRECTION(),
GET_MY_POSITION_X(),
GET_MY_POSITION_Y(),
GET_MY_POSITION_Z(),
#endif // USE_PTHREAD
OWL_BOOL_TO_STRING(GET_VERBOSE()),
OWL_BOOL_TO_STRING(GET_DISPLAY_CAPTURED())
@ -812,6 +890,21 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
printf(".. on the wrong port!") ;
putchar('\n') ;
}
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)) ;
break ;
default :
@ -973,9 +1066,9 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
request_time_str,
start_time_str,
request.antenna_signal_dbm - 0x100,
request.x_position,
request.y_position,
request.z_position,
owl_ntohf(request.x_position),
owl_ntohf(request.y_position),
owl_ntohf(request.z_position),
request.direction
) ;
}
@ -1172,7 +1265,12 @@ uint_fast16_t make_packet(uint8_t **packet)
{
uint8_t *pkt ;
uint_fast16_t size ; // Packet size
uint_fast16_t offset ; // Index used to create the packet
owl_timestamp request_time ;
float
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()) ;
owl_timestamp_now(&request_time) ;
@ -1185,11 +1283,29 @@ uint_fast16_t make_packet(uint8_t **packet)
request_time = owl_hton_timestamp(request_time) ;
size = sizeof(char) + sizeof(owl_timestamp) ;
offset = 0 ;
size =
sizeof(uint8_t) * 2 + sizeof(owl_timestamp) + sizeof(float) * 3 ;
pkt = malloc(size) ;
memset(&pkt[0], OWL_REQUEST_AUTOCALIBRATION, 1) ; // Packet type
memcpy(&pkt[1], &request_time, sizeof(request_time)) ;
// 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)) ;
#ifdef DEBUG
offset += sizeof(float) ;
assert(offset == size) ;
#endif // DEBUG
*packet = pkt ;
return size ;
@ -1225,13 +1341,13 @@ void print_usage()
" [-D autocalibration_ip]"
" [-P autocalibration_request_port ] [-a autocalibration_port]"
" [-H autocalibration_hello_delay] [-t autocalibration_delay]"
" [-n autocalibration_nb_packets]\n"
" [-n autocalibration_nb_packets] [direction x y z]\n"
"\t%s -h\n"
"\t%s -V\n"
"Main options:\n"
"\t-h\t\tPrint this help.\n"
"\t-V\t\tShow version.\n"
"\t-V\t\tShow version information.\n"
"\t-f config_file\tUse 'config_file' instead of the default"
" configuration file (%s). Available only if program was"
" compiled with libconfuse.\n"
@ -1255,16 +1371,19 @@ void print_usage()
"\t-A\t\t\tEnable autocalibration (default: disabled).\n"
"\t-D autocalib_ip\t\tDestination IP of the autocalibration"
"requests (default: aggregation_ip).\n"
"\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"
"\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"
"\t-H hello_delay\t\tTime between each hello"
" message sent to the aggregation server (default: %d s).\n"
"\t-t delay\t\tTime between each autocalibration"
" packet transmission (default: %d µs).\n"
"\t-n nb_packets\t\tNumber of packet transmitted"
" for one autocalibration request (default: %d).\n"
"\tdirection x y z\t\tThe coordinates of the listener"
" (direction is an integer; x, y, z are floats).\n"
"Other options:\n"
"\t-k\tKeep the monitor mode up on wifi_iface. Use it with buggy"
@ -1293,12 +1412,18 @@ void print_usage()
void print_version()
{
printf("This is OWLPS Listener, part of the Open Wireless Positioning"
printf("This is OwlPS Listener, part of the Open Wireless Positioning"
" System project.\n"
"\n"
"Version: %s.\n"
"Compilation-time options:\n"
"\tSupport for POSIX threads: %s.\n"
"\tSupport for configuration file (libconfuse): %s.\n",
#ifdef OWLPS_VERSION
OWLPS_VERSION
#else // OWLPS_VERSION
"unknown version"
#endif // OWLPS_VERSION
,
#ifdef USE_PTHREAD
"YES"
#else // USE_PTHREAD

View File

@ -1,5 +1,9 @@
.PHONY : all test doc prepare clean purge install uninstall style check
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Directories & files
SRC_DIR = src
OBJ_DIR = obj
TESTS_DIR = tests
@ -8,7 +12,7 @@ DOXYFILE = Doxyfile
# Installation directory
PREFIX = /usr/local
INSTALL_DIR = $(PREFIX)/bin
INSTALL_DIR = $(PREFIX)/bin
# System tools
RM = rm -fv
@ -19,7 +23,7 @@ MKDIR = mkdir -pv
# Other tools
STYLE = astyle --style=gnu --formatted
CPPCHECK = cppcheck --enable=all
CPPCHECK = cppcheck --quiet --enable=all
DOXYGEN = doxygen >/dev/null
# Compilation tools
@ -36,8 +40,11 @@ GXXFLAGS = $(DEBUG) -Wall -Wextra -I$(LIBOWLPS_DIR)
LD = $(CXX)
LDFLAGS = -lstdc++ -lm -lrt -lboost_program_options \
-L$(LIBOWLPS_DIR) -lowlps
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
# Targets
.PHONY : all test doc clean purge install uninstall style check
TARGET = owlps-positioning
OBJ_TARGET = $(OBJ_DIR)/$(TARGET).o
SOURCE_TARGET = $(SRC_DIR)/$(TARGET).cc
@ -113,14 +120,14 @@ SOURCE_TESTS = $(OBJ:$(OBJ_DIR)/%.o=$(TESTS_DIR)/%_test.hh)
OBJ_TESTS = $(TESTUTIL_OBJ) $(TESTSETUP_OBJ)
INCLUDES_TESTS = $(TESTS_DIR)/valuetraits.hh
all: prepare $(TARGET)
all: $(TARGET)
# Generic targets
$(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cc $(TESTS_DIR)/%.hh
$(CXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh
$(CXX) $(GXXFLAGS) -o $@ -c $<
$(MKDIR) $(OBJ_DIR) && $(CXX) $(GXXFLAGS) $(OWLPSFLAGS) -o $@ -c $<
%: $(OBJ_DIR)/%.o
$(LD) $(LDFLAGS) -o $@ $^
@ -289,15 +296,12 @@ $(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
$(TESTS_TARGET): $(TESTS_OBJ) $(OBJ_TESTS) $(OBJ) $(OBJ_NOTEST)
$(LD) $(LDFLAGS) -o $@ $^
test: prepare $(TESTS_TARGET)
test: $(TESTS_TARGET)
@$(TESTS_TARGET)
doc:
@$(DOXYGEN) $(DOXYFILE)
prepare:
@$(MKDIR) $(OBJ_DIR)
clean:
@$(RM) *~ */*~ *.orig */*.orig
@$(RM_RECURSIVE_VERBOSE) $(OBJ_DIR)

View File

@ -1,7 +1,4 @@
- Fix Makefile
The 'prepare' target *must* be called before the *.o targets.
- Write a class for Request::type?
CalibrationRequest::direction uses a dedicated class Direction, why
not Request::type? That would simplify writing of the type to
@ -38,9 +35,6 @@
° Différencier le pas pour X, Y et Z ?
° Régler le start & stop dans MultilaterationAlgorithm.
- Mobile
Attributs Viterbi ? (Cf. l'ancien clientinfo.hh.)
- Renommages de membres
° InputMedium :
°° current_line_nb et get_current_line_nb()
@ -48,10 +42,6 @@
° Input : get_next_request() > read_next_request()
° Area : p_min et p_max > coord_min et coord_max
- Doxygen
° Pourquoi une description détaillée placée dans un .cc ne s'affiche
pas pour operator<<() ?
- « C++ en action »
° Espaces de noms ? 109
° Réserver l'espace mémoire des vector avec reserve(). 217

View File

@ -117,7 +117,7 @@ bool CSVFileReader::read_point3d(Point3D &p)
}
void CSVFileReader::print_error_cast()
void CSVFileReader::print_error_cast() const
{
cerr
<< "Bad value « "

View File

@ -21,7 +21,7 @@ protected:
token_iterator ;
unsigned int current_field_nb ;
void print_error_cast(void) ;
void print_error_cast(void) const ;
public:
CSVFileReader(const std::string &filename,

View File

@ -150,9 +150,9 @@ const Request& InputUDPSocket::get_next_request()
calib_request->set_direction(Direction(request.direction)) ;
ReferencePoint position(request.x_position,
request.y_position,
request.z_position) ;
ReferencePoint position(owl_ntohf(request.x_position),
owl_ntohf(request.y_position),
owl_ntohf(request.z_position)) ;
const ReferencePoint &reference_point =
Stock::find_create_reference_point(position) ;
calib_request->set_reference_point(&reference_point) ;

View File

@ -1,53 +1,15 @@
#include "outputcsv.hh"
#include "request.hh"
#include "resultlist.hh"
#include "mobile.hh"
#include <sstream>
using namespace std ;
/* *** Operations *** */
const string OutputCSV::result_to_csv(const Result &result)
void OutputCSV::write(const Result &result)
{
ostringstream csv_line ;
csv_line << result.get_algorithm() ;
Point3D position = result.get_position() ;
csv_line
<< ';' << position.get_x()
<< ';' << position.get_y()
<< ';' << position.get_z() ;
return csv_line.str() ;
file.write_text(result.to_csv() + '\n') ;
}
const string OutputCSV::results_to_csv(const ResultList &results)
void OutputCSV::write(const ResultList &results)
{
ostringstream csv_line ;
const Request *const request = results.get_request() ;
if (request != NULL)
{
if (request->get_mobile() != NULL)
csv_line << request->get_mobile()->get_mac_addr() ;
csv_line
<< ';' << static_cast<uint_fast16_t>(request->get_type())
<< ';' << request->get_time_sent() ;
}
else
csv_line << ";;;" ;
const vector<Result> &res = results.get_results() ;
for (vector<Result>::const_iterator r = res.begin() ; r != res.end() ;
++r)
csv_line << ';' << result_to_csv(*r) ;
return csv_line.str() ;
file.write_text(results.to_csv() + '\n') ;
}

View File

@ -14,9 +14,6 @@ class OutputCSV: public OutputMedium
protected:
TextFileWriter file ;
const std::string result_to_csv(const Result &result) ;
const std::string results_to_csv(const ResultList &results) ;
public:
OutputCSV(const std::string &filename):
file(filename) {}
@ -30,17 +27,5 @@ public:
/* *** Operations *** */
inline void OutputCSV::write(const Result &result)
{
file.write_text(result_to_csv(result) + '\n') ;
}
inline void OutputCSV::write(const ResultList &results)
{
file.write_text(results_to_csv(results) + '\n') ;
}
#endif // _OWLPS_POSITIONING_OUTPUTCSV_HH_

View File

@ -1,18 +1,15 @@
#include "outputudpsocket.hh"
#include "request.hh"
#include "resultlist.hh"
#include "posexcept.hh"
#include <owlps.h>
#include <sstream>
#include <iostream>
#include <netdb.h>
#include <cstring>
#include <cstdio> // For perror()
using namespace std ;
struct hostent *hostInfo ;
struct sockaddr_in serverAddress ;
/* *** Constructors *** */
@ -22,13 +19,15 @@ OutputUDPSocket::OutputUDPSocket(const string &_remote_host,
const uint_fast16_t _remote_port):
remote_host(_remote_host), remote_port(_remote_port)
{
init_socket() ;
if (! init_socket())
throw error_opening_output_file("UDP socket") ;
}
OutputUDPSocket::~OutputUDPSocket()
{
kill_socket() ;
close_socket() ;
}
@ -36,56 +35,63 @@ OutputUDPSocket::~OutputUDPSocket()
/* *** Operations *** */
void OutputUDPSocket::write(const ResultList &results)
/**
* @return true if the socket were successfully opened, false in case of
* error.
*/
bool OutputUDPSocket::init_socket()
{
// Not implemented
sockfd = owl_create_udp_trx_socket(remote_host.c_str(), remote_port,
&server_info, &client_info) ;
return sockfd >= 0 ;
}
/**
* Normally, the socket is closed automatically by the destructor. Use
* this if you want to close the socket prematurely.
* #sockfd is set to -1, even in case of error.
* @return \em true if the socket were successfully closed or were not
* opened.
* @return \em false in case of error.
*/
bool OutputUDPSocket::close_socket()
{
if (sockfd >= 0)
{
if (close(sockfd))
{
perror("Cannot close UDP socket") ;
return false ;
}
sockfd = -1 ;
}
return true ;
}
void OutputUDPSocket::write(const Result &result)
{
string timestampXYZ;
ostringstream os;
Point3D position = result.get_position() ;
os
<< position.get_x() << ';'
<< position.get_y() << ';'
<< position.get_z() ;
timestampXYZ = os.str() ;
cout << timestampXYZ << '\n' ;
send_data(timestampXYZ);
send_data(result.to_csv()) ;
}
void OutputUDPSocket::init_socket()
void OutputUDPSocket::write(const ResultList &results)
{
cout << "Initialisation socket..." << endl;
hostInfo = gethostbyname(remote_host.c_str());
socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
serverAddress.sin_family = hostInfo->h_addrtype;
memcpy((char *) &serverAddress.sin_addr.s_addr,
hostInfo->h_addr_list[0], hostInfo->h_length);
serverAddress.sin_port = htons(remote_port);
send_data(results.to_csv()) ;
}
void OutputUDPSocket::send_data(string data)
/**
* Sends the text buffer 'data'.
*/
void OutputUDPSocket::send_data(const string &data)
{
if (sendto(socketDescriptor, data.c_str(), data.size(), 0,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0)
{
cerr << "Émission du message impossible\n";
close(socketDescriptor);
}
}
void OutputUDPSocket::kill_socket()
{
cout << "Fermeture de la socket..." << endl;
close(socketDescriptor);
ssize_t nsent = sendto(sockfd, data.c_str(), data.size(), 0,
(struct sockaddr *) &server_info,
sizeof(server_info)) ;
if (nsent != static_cast<ssize_t>(data.size()))
perror("Error sending result data") ;
}

View File

@ -5,21 +5,28 @@
#include <string>
#include <stdint.h> // <cstdint> is not C++ 98 compliant
#include <arpa/inet.h>
/// Sends results to an UDP socket
/// Sends results to a remote host by UDP
/**
* The results are sent through an UDP socket as a CSV string value. The
* format used is the same as in OutputCSV.
*/
class OutputUDPSocket: public OutputMedium
{
private:
int socketDescriptor ;
protected:
int sockfd ;
std::string remote_host ;
uint_fast16_t remote_port ;
struct sockaddr_in server_info ;
struct sockaddr_in client_info ;
/** @name Operations */
//@{
/// Initialises the socket
void init_socket(void) ;
void kill_socket(void) ;
void send_data(std::string msg) ;
bool init_socket(void) ;
void send_data(const std::string &data) ;
//@}
public:
@ -29,9 +36,10 @@ public:
/** @name Operations */
//@{
/// Initialises the socket
void write(const Result &result) ;
void write(const ResultList &results) ;
/// Closes the socket
bool close_socket(void) ;
//@}
} ;

View File

@ -1,6 +1,10 @@
#include "result.hh"
#include "request.hh"
#include <sstream>
using namespace std ;
/* *** Operators *** */
@ -27,7 +31,25 @@ bool Result::operator==(const Result &source) const
std::ostream& operator<<(std::ostream &os, const Result &r)
/**
* @return the result as a CSV string, \em without trailing '\n'.
*/
const string Result::to_csv() const
{
ostringstream csv_line ;
csv_line
<< algorithm
<< ';' << position.get_x()
<< ';' << position.get_y()
<< ';' << position.get_z() ;
return csv_line.str() ;
}
std::ostream& operator<<(ostream &os, const Result &r)
{
os
<< "The result of the algorithm " << r.algorithm

View File

@ -32,6 +32,12 @@ public:
bool operator!=(const Result &source) const ;
//@}
/** @name Conversion accessors */
//@{
/// Convert to a CSV string
const std::string to_csv(void) const ;
//@}
/// Displays a Result
friend std::ostream& operator<<(std::ostream &os, const Result &r) ;
} ;

View File

@ -1,5 +1,8 @@
#include "resultlist.hh"
#include "request.hh"
#include "mobile.hh"
#include <sstream>
using namespace std ;
@ -39,6 +42,36 @@ bool ResultList::operator==(const ResultList &source) const
/* *** Conversion accessors *** */
/**
* @return the results as a CSV string, \em without trailing '\n'.
*/
const string ResultList::to_csv() const
{
ostringstream csv_line ;
if (request != NULL)
{
if (request->get_mobile() != NULL)
csv_line << request->get_mobile()->get_mac_addr() ;
csv_line
<< ';' << static_cast<uint_fast16_t>(request->get_type())
<< ';' << request->get_time_sent() ;
}
else
csv_line << ";;;" ;
for (vector<Result>::const_iterator r = results.begin() ;
r != results.end() ; ++r)
csv_line << ';' << r->to_csv() ;
return csv_line.str() ;
}
ostream& operator<<(ostream &os, const ResultList &r)
{
if (r.request == NULL)

View File

@ -7,6 +7,8 @@ class Request ;
#include <vector>
#include <ostream>
/// \brief List of \link Result results \endlink of a single Request,
/// computed by one or more positioning algorithm
class ResultList
{
protected:
@ -39,6 +41,12 @@ public:
bool operator!=(const ResultList &source) const ;
//@}
/** @name Conversion accessors */
//@{
/// Convert to a CSV string
const std::string to_csv(void) const ;
//@}
/// Displays a ResultList
friend std::ostream& operator<<(std::ostream &os,
const ResultList &r) ;

View File

@ -1,6 +1,8 @@
#include "textfilereader.hh"
#include "posexcept.hh"
#include <iostream>
using namespace std ;
@ -15,15 +17,26 @@ using namespace std ;
TextFileReader::TextFileReader(const string &_file_name):
file_name(_file_name), current_line_nb(0)
{
file.open(file_name.c_str()) ;
if (! file)
throw error_opening_input_file(file_name) ;
if (file_name == "-")
{
file_buf = file.rdbuf() ;
file.std::ios::rdbuf(std::cin.rdbuf()) ;
}
else
{
file.open(file_name.c_str()) ;
if (! file)
throw error_opening_input_file(file_name) ;
}
}
TextFileReader::~TextFileReader()
{
file.close() ;
if (file_name == "-")
file.std::ios::rdbuf(file_buf) ;
else
file.close() ;
}

View File

@ -4,12 +4,20 @@
#include <string>
#include <fstream>
/// Read text from a file, line by line
/// Reads text from a file, line by line
/**
* If the file name is a dash ('-'), the standard input is used.
*/
class TextFileReader
{
protected:
/// Name of the input file
std::string file_name ;
/// Stream associated with the file
std::ifstream file ;
/// Original rdbuf of the stream
std::streambuf *file_buf ;
/// Number of the last line read
unsigned int current_line_nb ;
/// Checks if the file is readable and closes it if not

View File

@ -2,6 +2,8 @@
#include "configuration.hh"
#include "posexcept.hh"
#include <iostream>
using namespace std ;
@ -10,21 +12,33 @@ using namespace std ;
/**
* @param _file_name The name of the file to open.
* @param _file_name The name of the file to open ('-' for the standard
* output).
* @throw error_opening_input_file if the file cannot be opened.
*/
TextFileWriter::TextFileWriter(const string &_file_name):
file_name(_file_name)
{
file.open(file_name.c_str()) ;
if (! file)
throw error_opening_output_file(file_name) ;
if (file_name == "-")
{
file_buf = file.rdbuf() ;
file.std::ios::rdbuf(std::cout.rdbuf()) ;
}
else
{
file.open(file_name.c_str()) ;
if (! file)
throw error_opening_output_file(file_name) ;
}
}
TextFileWriter::~TextFileWriter()
{
file.close() ;
if (file_name == "-")
file.std::ios::rdbuf(file_buf) ;
else
file.close() ;
}

View File

@ -4,12 +4,19 @@
#include <string>
#include <fstream>
/// Write text to a file
/// Writes text to a file
/**
* If the file name is a dash ('-'), the standard output is used.
*/
class TextFileWriter
{
private:
/// Name of the output file
std::string file_name ;
/// Stream associated with the file
std::ofstream file ;
/// Original rdbuf of the stream
std::streambuf *file_buf ;
public:
TextFileWriter(const std::string &_file_name) ;

View File

@ -72,10 +72,11 @@ void UserInterface::fill_options()
void UserInterface::fill_cli_options()
{
cli_options->add_options()
("help,h", "Print help")
("help,h", "Print help.")
("version,V", "Print version information.")
("config-file,f", po::value<string>()
->default_value(DEFAULT_CONFIG_FILE_NAME),
"Alternative configuration file")
"Alternative configuration file.")
; // End of options
}
@ -187,7 +188,7 @@ this option more than once. Allowed: Terminal, CSV, UDP. \
If this option is absent, results will be printed on the terminal.")
("output.csv-file", po::value<string>(),
"CSV file to use for output (when output.medium = CSV).")
("output.udp-host", po::value<int>(),
("output.udp-host", po::value<string>(),
"Host to which the UDP data is sent (when output.medium = UDP).")
("output.udp-port", po::value<int>()
->default_value(MOBILE_DEFAULT_PORT),
@ -214,7 +215,7 @@ void UserInterface::fill_misc_options()
void UserInterface::parse_options()
{
parse_command_line() ;
print_usage_and_exit_if_requested() ;
print_information_and_exit_if_requested() ;
parse_file() ;
@ -231,13 +232,34 @@ void UserInterface::parse_command_line() const
}
void UserInterface::print_usage_and_exit_if_requested() const
void UserInterface::print_information_and_exit_if_requested() const
{
bool exit_program = false ;
// Print version if requested
if (Configuration::is_configured("version"))
{
cout
<< "This is OwlPS Positioning, part of the Open Wireless"
<< " Positioning System project.\nVersion: " <<
#ifdef OWLPS_VERSION
OWLPS_VERSION
#else // OWLPS_VERSION
"unknown version"
#endif // OWLPS_VERSION
<< ".\n" ;
exit_program = true ;
}
// Print usage if requested
if (Configuration::is_configured("help"))
{
cout << *cli_options ;
exit(0) ;
exit_program = true ;
}
if (exit_program)
exit(0) ;
}

View File

@ -36,8 +36,8 @@ protected:
void parse_command_line(void) const ;
void parse_file(void) const ;
/// If help was requested by user, displays accepted options and exit
void print_usage_and_exit_if_requested(void) const ;
/// Print usage and/or version information if requested by the user
void print_information_and_exit_if_requested(void) const ;
//@}
public:

View File

@ -76,7 +76,7 @@ bool Waypoint::operator==(const Waypoint &wp) const
}
Waypoint::operator string() const
Waypoint::operator std::string() const
{
ostringstream csv ;
csv << (Point3D) *this ;