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

View File

@ -16,9 +16,10 @@
* 'iface' if specified (if you want the interface to be selected, * 'iface' if specified (if you want the interface to be selected,
* automatically, this parameter should be NULL or an empty string). * automatically, this parameter should be NULL or an empty string).
*/ */
int owlclient_create_trx_socket(char *dest_ip, uint_fast16_t dest_port, int owlclient_create_trx_socket(const char *const dest_ip,
struct sockaddr_in *server, const uint_fast16_t dest_port,
char *iface) struct sockaddr_in *const server,
const char *const iface)
{ {
struct sockaddr_in client ; 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'. */ /* 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, if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface,
strlen(iface) + 1) == -1) 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 owlclient_send_request(const int sockfd,
void *packet, uint_fast16_t packet_size, const struct sockaddr_in *const server,
uint_fast16_t nb_pkt, uint_fast32_t delay) 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 ; uint_fast16_t i ;
if (nb_pkt == 0)
return ;
#ifdef DEBUG #ifdef DEBUG
printf("Sent packets: ") ; printf("Sent packets: ") ;
#endif // DEBUG #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 owlclient_send_packet(const int sockfd,
void *packet, uint_fast16_t packet_size) 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, ssize_t nsent = sendto(sockfd, packet, packet_size, 0,
(struct sockaddr *) server, (struct sockaddr *) server,

View File

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

View File

@ -17,6 +17,8 @@
#include <net/if.h> #include <net/if.h>
#include <iwlib.h> #include <iwlib.h>
#include <assert.h>
#define DEBUG #define DEBUG
@ -24,13 +26,16 @@ owl_bool owl_run = TRUE ;
/* *** Miscellaneous functions *** */
/* /*
* Converts a MAC address from bytes to string. * Converts a MAC address from bytes to string.
* The string is allocated in a static buffer, and will be overwritten * The string is allocated in a static buffer, and will be overwritten
* each time this function is called. * each time this function is called.
* This function is not thread-safe! * 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] ; static char mac_str[OWL_ETHER_ADDR_STRLEN] ;
owl_mac_bytes_to_string_r(mac_binary, mac_str) ; 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. * Converts a MAC address from bytes to string.
* 'mac_str' must be allocated by the caller. * 'mac_str' must be allocated by the caller.
* This function is thread-safe. * 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]) char mac_str[OWL_ETHER_ADDR_STRLEN])
{ {
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", 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. * Converts a IEEE 802.11 frequency into a channel number.
* Returns 0 if the frequency does not correspond to an official channel. * 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 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. * Sets the owl_timestamp 'now' at the current time.
* Returns 0 in case of success non-zero otherwise. * 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 ; int ret ;
struct timespec now_ts ; struct timespec now_ts ;
@ -133,7 +154,6 @@ int owl_timestamp_now(owl_timestamp *now)
} }
/* /*
* Returns a owl_timestamp from a struct timespec. * 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. * 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(const owl_timestamp d1,
owl_bool owl_timestamp_equals(owl_timestamp d1, owl_timestamp d2) const owl_timestamp d2)
{ {
return d1.tv_sec == d2.tv_sec && d1.tv_nsec == d2.tv_nsec ; return d1.tv_sec == d2.tv_sec && d1.tv_nsec == d2.tv_nsec ;
} }
owl_bool owl_timestamp_is_null(const owl_timestamp d)
owl_bool owl_timestamp_is_null(owl_timestamp d)
{ {
return d.tv_sec == 0 && d.tv_nsec == 0 ; return d.tv_sec == 0 && d.tv_nsec == 0 ;
} }
/* /*
* Converts a owl_timestamp date value into milliseconds. * 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 ; return (uint64_t) d.tv_sec * 1000u + (uint64_t) d.tv_nsec / 1000000lu ;
} }
/* /*
* Converts a owl_timestamp date value into a printable string. * Converts a owl_timestamp date value into a printable string.
* 'dst' must be an allocated array of at least owl_timestamp_STR_LEN * 'dst' must be an allocated array of at least owl_timestamp_STR_LEN
* characters. * 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, snprintf(dst, OWL_TIMESTAMP_STR_LEN, "%"PRIu32".%"PRIu32,
src.tv_sec, src.tv_nsec) ; src.tv_sec, src.tv_nsec) ;
} }
/* /*
* Returns the time (in milliseconds) between two dates. * 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. * 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. * 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 ; owl_timestamp date ;
d.tv_sec = htonl(date.tv_sec) ; date.tv_sec = htonl(d.tv_sec) ;
d.tv_nsec = htonl(date.tv_nsec) ; date.tv_nsec = htonl(d.tv_nsec) ;
return d ; return date ;
} }
/* /*
* Converts a owl_timestamp from network endianess to host endianess. * 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 ; owl_timestamp date ;
d.tv_sec = ntohl(date.tv_sec) ; date.tv_sec = ntohl(d.tv_sec) ;
d.tv_nsec = ntohl(date.tv_nsec) ; date.tv_nsec = ntohl(d.tv_nsec) ;
return d ; return date ;
} }
/* /*
* Compares two MAC addresses. * Swap bytes composing a float.
* Returns TRUE if they are identical, FALSE otherwise. * 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 ; float ret ;
for (i = 0 ; i < ETHER_ADDR_LEN ; ++i) char
if(mac1[i] != mac2[i]) *f_bytes = (char*) &f,
return FALSE ; *ret_bytes = (char*) &ret ;
return TRUE ;
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. * Creates a UDP transmission socket and returns its descriptor.
* Parameters: * 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 * - client_description (in/out): the structure in which the client
* description will be saved. * description will be saved.
*/ */
int owl_create_udp_trx_socket(char *server_address, int owl_create_udp_trx_socket(const char *const server_address,
uint_fast16_t server_port, const uint_fast16_t server_port,
struct sockaddr_in *server_description, struct sockaddr_in *const server_description,
struct sockaddr_in *client_description) struct sockaddr_in *const client_description)
{ {
int sockfd ; // Socket descriptor int sockfd ; // Socket descriptor
/* Ceate the UDP socket */ /* Create the UDP socket */
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ; sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
if (sockfd < 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. * Creates a UDP reception socket and returns its descriptor.
* Parameters: * Parameters:
* - port: port on which the socket listens. * - 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 int sockfd ; // Socket descriptor
struct sockaddr_in server_description ; // Server structure 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. * 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 ; struct iwreq wrq ;
int sockfd = iw_sockets_open() ; 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'. * Sets the IEEE 802.11 channel of the interface 'iface'.
* 'channel' must be an integer between 1 and 14. * '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 ; struct iwreq wrq ;
int sockfd = iw_sockets_open() ; 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 * Switches alternatively the Wi-Fi channel of the IEEE 802.11 interface
* 'iface' to 4 or 11. * '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 ; uint_fast16_t channel ;
struct iwreq wrq ; struct iwreq wrq ;
@ -425,7 +449,7 @@ int owl_iface_channel_hop(char *iface)
if (ioctl(sockfd, SIOCGIWFREQ, &wrq) == -1) 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 ; return ERR_READING_CHANNEL ;
} }
// The following is not very clean: we should use iw_freq2float(), // 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. * Generic signal handler for SIGINT.
*/ */
void owl_sigint_handler(int num) void owl_sigint_handler(const int num)
{ {
if (num != SIGINT) if (num != SIGINT)
{ {
@ -468,9 +495,10 @@ void owl_sigint_handler(int num)
} }
/*
/* Gestionnaire de signal générique pour SIGTERM */ * Generic signal handler for SIGTERM.
void owl_sigterm_handler(int num) */
void owl_sigterm_handler(const int num)
{ {
if (num != SIGTERM) if (num != SIGTERM)
{ {
@ -484,16 +512,19 @@ void owl_sigterm_handler(int num)
/* *** Thread-related functions *** */
/* /*
* Closes the file descriptor 'fd'. * Closes the file descriptor 'fd'.
* 'fd' must be passed as an int pointer (int*). * '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) if (fd == NULL)
return ; return ;
int *file_desc = fd ; const int *const file_desc = fd ;
if (close(*file_desc) != 0) if (close(*file_desc) != 0)
perror("Error closing file descriptor") ; perror("Error closing file descriptor") ;
#ifdef DEBUG #ifdef DEBUG
@ -504,13 +535,12 @@ void owl_close_fd(void *fd)
} }
/* /*
* Closes the stream 'file'. * Closes the stream 'file'.
* 'file' must be passed as a pointer on a pointer of FILE (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. * 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) if (file == NULL)
return ; return ;

View File

@ -232,44 +232,59 @@ extern owl_bool owl_run ;
/* Function headers */ /* Function headers */
// Misc // Misc
const char* owl_mac_bytes_to_string(uint8_t *mac_binary) ; const char* owl_mac_bytes_to_string(const uint8_t *const mac_binary) ;
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]) ; char mac_str[OWL_ETHER_ADDR_STRLEN]) ;
owl_bool owl_mac_equals(uint8_t *mac1, uint8_t *mac2) ; owl_bool owl_mac_equals(const uint8_t *const mac1,
uint_fast8_t owl_frequency_to_channel(uint_fast16_t channel) ; const uint8_t *const mac2) ;
uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel) ;
// Time // 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_timespec_to_timestamp(const struct timespec d) ;
owl_timestamp owl_timeval_to_timestamp(const struct timeval 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(const owl_timestamp d1,
owl_bool owl_timestamp_equals(owl_timestamp d1, owl_timestamp d2) ; const owl_timestamp d2) ;
owl_bool owl_timestamp_is_null(owl_timestamp d) ; owl_bool owl_timestamp_is_null(const owl_timestamp d) ;
uint64_t owl_timestamp_to_ms(owl_timestamp date) ; 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, uint_fast32_t owl_time_elapsed_ms(const owl_timestamp d1,
const owl_timestamp d2) ; const owl_timestamp d2) ;
owl_timestamp owl_time_elapsed(const owl_timestamp d1, owl_timestamp owl_time_elapsed(const owl_timestamp d1,
const owl_timestamp d2) ; 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 // Network
int owl_create_udp_trx_socket(char *server_address, int owl_create_udp_trx_socket(const char *const server_address,
uint_fast16_t server_port, const uint_fast16_t server_port,
struct sockaddr_in *server_description, struct sockaddr_in *const server_description,
struct sockaddr_in *client_description) ; struct sockaddr_in *const client_description) ;
int owl_create_udp_listening_socket(uint_fast16_t port) ; int owl_create_udp_listening_socket(const uint_fast16_t port) ;
int owl_iface_mode_monitor(char *iface) ; int owl_iface_mode_monitor(const char *const iface) ;
int owl_iface_set_channel(char *iface, uint_fast8_t channel) ; int owl_iface_set_channel(const char *const iface,
int owl_iface_channel_hop(char *iface) ; const uint_fast8_t channel) ;
int owl_iface_channel_hop(const char *const iface) ;
// Signals // Signals
void owl_sigint_handler(int num) ; void owl_sigint_handler(const int num) ;
void owl_sigterm_handler(int num) ; void owl_sigterm_handler(const int num) ;
// Threads // Threads
void owl_close_fd(void *fd) ; void owl_close_fd(void *const fd) ;
void owl_close_file(void *file) ; void owl_close_file(void *const file) ;
/* Macros */ /* Macros */

View File

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

View File

@ -11,7 +11,7 @@
/* Arguments & program configuration */ /* 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_CONFIG_FILE "/usr/local/etc/owlps/owlps-aggregator.conf"
#define DEFAULT_AGGREGATE_TIMEOUT 1500 // milliseconds #define DEFAULT_AGGREGATE_TIMEOUT 1500 // milliseconds
#define DEFAULT_KEEP_TIMEOUT 3000 // milliseconds #define DEFAULT_KEEP_TIMEOUT 3000 // milliseconds
@ -112,5 +112,6 @@ void order_send(ap_list *ap) ;
void free_ap_list(void) ; void free_ap_list(void) ;
void print_usage(void) ; void print_usage(void) ;
void print_version(void) ;
#endif // _OWLPS_AGGREGATOR_H_ #endif // _OWLPS_AGGREGATOR_H_

View File

@ -188,19 +188,30 @@ void parse_config_file(int argc, char **argv)
CFG_END() 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 ; int opt ;
do while ((opt = getopt(argc, argv, OPTIONS)) != -1)
opt = getopt(argc, argv, OPTIONS) ;
while (opt != 'f' && opt != -1) ;
if (opt == 'f')
{ {
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ; switch (opt)
strcpy(config_file, optarg) ; {
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 = config_file =
malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ; malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ;
@ -415,6 +426,9 @@ int read_loop(int sockfd)
// Endianess conversions: // Endianess conversions:
request.request_time = owl_ntoh_timestamp(request.request_time) ; request.request_time = owl_ntoh_timestamp(request.request_time) ;
request.start_time = owl_ntoh_timestamp(request.start_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")) if (cfg_getbool(cfg, "verbose"))
{ {
@ -436,7 +450,7 @@ int read_loop(int sockfd)
"\tPosition X: %f\n" "\tPosition X: %f\n"
"\tPosition Y: %f\n" "\tPosition Y: %f\n"
"\tPosition Z: %f\n" "\tPosition Z: %f\n"
"\tDirection: %hhd\n" "\tDirection: %"PRIu8"\n"
, ,
request.type, request.type,
owl_mac_bytes_to_string(request.ap_mac_addr_bytes), owl_mac_bytes_to_string(request.ap_mac_addr_bytes),
@ -1228,9 +1242,12 @@ void print_usage()
" [-K ap_keep_timeout]" " [-K ap_keep_timeout]"
" [-C ap_check_interval]" " [-C ap_check_interval]"
"\n" "\n"
"\t%s -h\n"
"\t%s -V\n"
"Main options:\n" "Main options:\n"
"\t-h\t\tPrint this help.\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" "\t-f config_file\tUse 'config_file' instead of the default"
" configuration file (%s).\n" " configuration file (%s).\n"
"\t-v\t\tBe verbose (print detailed info on each received" "\t-v\t\tBe verbose (print detailed info on each received"
@ -1249,7 +1266,7 @@ void print_usage()
" treated (default: %d).\n" " treated (default: %d).\n"
"\t-t aggregate_timeout\tRequests are stored during" "\t-t aggregate_timeout\tRequests are stored during"
" 'aggregate_timeout' milliseconds before to be grouped" " '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" "\t-k keep_timeout\t\tAggregated requests are kept during"
" 'keep_timeout' milliseconds (default: %d ms).\n" " 'keep_timeout' milliseconds (default: %d ms).\n"
"\t-c check_interval\tTime between two checks of the stored" "\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" " checks of the stored APs (default: %d ms).\n"
, ,
program_name, program_name,
program_name,
program_name,
DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE,
POSITIONER_DEFAULT_IP, POSITIONER_DEFAULT_IP,
POSITIONER_DEFAULT_PORT, POSITIONER_DEFAULT_PORT,
@ -1277,3 +1296,17 @@ void print_usage()
DEFAULT_AP_CHECK_INTERVAL 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 # Répertoire d'installation
PREFIX=/usr/local PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/bin INSTALL_DIR= $(PREFIX)/bin
@ -29,7 +34,7 @@ XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC PICFLAG = -fPIC
LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client
STATIC_LIBS = -liw -lm -lrt STATIC_LIBS = -liw -lm -lrt
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ## ## Cibles de compilation standard ##
@ -42,7 +47,7 @@ all : dynamic static
% : %.o % : %.o
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS) $(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
%.o : %.c $(HEADER) %.o : %.c $(HEADER)
$(CC) $(XCFLAGS) -c $< $(CC) $(XCFLAGS) $(OWLPSFLAGS) -c $<
# Compilation du programme # Compilation du programme
$(TARGET) : $(TARGET).o $(HEADER) $(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 # Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = /arm TOOLCHAIN_PREFIX = /arm
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/bin TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/bin
@ -39,7 +44,7 @@ STATIC_LIBS = $(LOWLPSA) $(LIBS)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS) LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ## ## Cibles de compilation standard ##
@ -56,7 +61,7 @@ all: semistatic static
# $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(DYNAMIC_LIBS) # $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(DYNAMIC_LIBS)
%: %.o %: %.o
$(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(SEMISTATIC_LIBS) $(CC) $(STRIPFLAGS) $(XCFLAGS) $(OWLPSFLAGS) -o $@ $^ $(LDFLAGS) $(SEMISTATIC_LIBS)
%.static: %.o %.static: %.o
$(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(STATIC_LIBS) \ $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LDFLAGS) $(STATIC_LIBS) \

View File

@ -146,6 +146,9 @@ void parse_main_options(int argc, char **argv)
case 't' : case 't' :
options.delay = strtol(optarg, NULL, 0) ; options.delay = strtol(optarg, NULL, 0) ;
break ; break ;
case 'V' :
print_version() ;
exit(0) ;
default : default :
print_usage() ; print_usage() ;
exit(ERR_BAD_USAGE) ; exit(ERR_BAD_USAGE) ;
@ -219,7 +222,7 @@ void check_configuration()
else else
options.nb_pkt = DEFAULT_NBPKT_NORMAL ; options.nb_pkt = DEFAULT_NBPKT_NORMAL ;
} }
// Calibration request but bad direction // Calibration request but bad direction
if (is_calibration_request) if (is_calibration_request)
if (options.direction < OWL_DIRECTION_MIN || if (options.direction < OWL_DIRECTION_MIN ||
@ -271,7 +274,7 @@ void print_configuration()
"\tDelay: %"PRIuFAST32"\n" "\tDelay: %"PRIuFAST32"\n"
"\tNumber of packets: %"PRIuFAST16"\n" "\tNumber of packets: %"PRIuFAST16"\n"
"\tListening port: %"PRIuFAST16"\n" "\tListening port: %"PRIuFAST16"\n"
"\tDirection: %d\n" "\tDirection: %"PRIu8"\n"
"\tX: %f\n" "\tX: %f\n"
"\tY: %f\n" "\tY: %f\n"
"\tZ: %f\n" "\tZ: %f\n"
@ -341,6 +344,9 @@ void make_packet()
printf("Direction = %d, X = %f, Y = %f, Z = %f\n", printf("Direction = %d, X = %f, Y = %f, Z = %f\n",
packet[offset - 1], options.x, options.y, options.z) ; packet[offset - 1], options.x, options.y, options.z) ;
#endif // DEBUG #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)) ; memcpy(&packet[offset], &options.x, sizeof(float)) ;
offset += sizeof(float) ; offset += sizeof(float) ;
memcpy(&packet[offset], &options.y, sizeof(float)) ; memcpy(&packet[offset], &options.y, sizeof(float)) ;
@ -546,6 +552,7 @@ void print_usage()
"\n" "\n"
"Options:\n" "Options:\n"
"\t-h\t\tPrint this help.\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-d dest_ip\tDestination IP address of the localisation request.\n"
"\t-p dest_port\tDestination port of the localisation request" "\t-p dest_port\tDestination port of the localisation request"
" (default: %d).\n" " (default: %d).\n"
@ -572,3 +579,17 @@ void print_usage()
MOBILE_DEFAULT_PORT 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 #define DEFAULT_DELAY_NORMAL 25000 // Localisation request
/* Program arguments (getopt string) */ /* Program arguments (getopt string) */
#define OPTIONS "d:hi:l::n:p:t:" #define OPTIONS "d:hi:l::n:p:t:V"
/* Function headers */ /* Function headers */
@ -37,6 +37,7 @@ void send_labview(char*) ;
void string2data(char*) ; void string2data(char*) ;
void* thread_send(void*) ; void* thread_send(void*) ;
void print_error(char*) ; void print_error(char*) ;
void print_version(void) ;
typedef struct result result; typedef struct result result;
/* Struct */ /* Struct */

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe || echo 'UNKNOWN_VERSION')
endif
# Répertoire d'installation # Répertoire d'installation
PREFIX=/usr/local PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/bin INSTALL_DIR= $(PREFIX)/bin
@ -27,6 +32,7 @@ CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \
DEPFLAGS = -MMD DEPFLAGS = -MMD
XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC PICFLAG = -fPIC
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client LIBS = -L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPSCLIENT_DIR) -lowlps-client
STATIC_LIBS = -liw -lm -lrt STATIC_LIBS = -liw -lm -lrt
@ -42,7 +48,7 @@ all : dynamic static
% : %.o % : %.o
$(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS) $(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS)
%.o : %.c $(HEADER) %.o : %.c $(HEADER)
$(CC) $(XCFLAGS) -c $< $(CC) $(XCFLAGS) $(OWLPSFLAGS) -c $<
# Compilation du programme # Compilation du programme
$(TARGET) : $(TARGET).o $(HEADER) $(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 # Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09 TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/staging_dir/toolchain-mips_gcc4.1.2/bin 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 LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS) LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ## ## 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 # Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/10.03 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 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 LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include
LDFLAGS = $(IATHEROS) $(LATHEROS) LDFLAGS = $(IATHEROS) $(LATHEROS)
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
## Cibles de compilation standard ## ## Cibles de compilation standard ##

View File

@ -26,7 +26,7 @@
#define DEFAULT_DELAY_NORMAL 25000 // Localisation request #define DEFAULT_DELAY_NORMAL 25000 // Localisation request
/* Program arguments (getopt string) */ /* Program arguments (getopt string) */
#define OPTIONS "d:hi:l::n:p:t:" #define OPTIONS "d:hi:l::n:p:t:V"
/* Function headers */ /* Function headers */
@ -43,6 +43,7 @@ void make_packet(void) ;
void send_request(void) ; void send_request(void) ;
void receive_position(void) ; void receive_position(void) ;
void print_usage(void) ; void print_usage(void) ;
void print_version(void) ;
/* Options */ /* Options */
@ -162,6 +163,9 @@ void parse_main_options(int argc, char **argv)
case 't' : case 't' :
options.delay = strtol(optarg, NULL, 0) ; options.delay = strtol(optarg, NULL, 0) ;
break ; break ;
case 'V' :
print_version() ;
exit(0) ;
default : default :
print_usage() ; print_usage() ;
exit(ERR_BAD_USAGE) ; exit(ERR_BAD_USAGE) ;
@ -287,7 +291,7 @@ void print_configuration()
"\tDelay: %"PRIuFAST32"\n" "\tDelay: %"PRIuFAST32"\n"
"\tNumber of packets: %"PRIuFAST16"\n" "\tNumber of packets: %"PRIuFAST16"\n"
"\tListening port: %"PRIuFAST16"\n" "\tListening port: %"PRIuFAST16"\n"
"\tDirection: %d\n" "\tDirection: %"PRIu8"\n"
"\tX: %f\n" "\tX: %f\n"
"\tY: %f\n" "\tY: %f\n"
"\tZ: %f\n" "\tZ: %f\n"
@ -348,6 +352,9 @@ void make_packet()
printf("Direction = %d, X = %f, Y = %f, Z = %f\n", printf("Direction = %d, X = %f, Y = %f, Z = %f\n",
packet[offset - 1], options.x, options.y, options.z) ; packet[offset - 1], options.x, options.y, options.z) ;
#endif // DEBUG #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)) ; memcpy(&packet[offset], &options.x, sizeof(float)) ;
offset += sizeof(float) ; offset += sizeof(float) ;
memcpy(&packet[offset], &options.y, sizeof(float)) ; memcpy(&packet[offset], &options.y, sizeof(float)) ;
@ -405,6 +412,7 @@ void print_usage()
"\n" "\n"
"Options:\n" "Options:\n"
"\t-h\t\tPrint this help.\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-d dest_ip\tDestination IP address of the localisation request.\n"
"\t-p dest_port\tDestination port of the localisation request" "\t-p dest_port\tDestination port of the localisation request"
" (default: %d).\n" " (default: %d).\n"
@ -431,3 +439,17 @@ void print_usage()
MOBILE_DEFAULT_PORT 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 # Répertoire d'installation
PREFIX=/usr/local PREFIX=/usr/local
INSTALL_DIR= $(PREFIX)/sbin INSTALL_DIR= $(PREFIX)/sbin
@ -27,7 +32,8 @@ CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \
DEPFLAGS = -MMD DEPFLAGS = -MMD
XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG = -fPIC 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 \ LIBS = -L$(LIBOWLPS_DIR) -lowlps \
-L$(LIBOWLPSCLIENT_DIR) -lowlps-client \ -L$(LIBOWLPSCLIENT_DIR) -lowlps-client \
-lpcap -lpcap

View File

@ -1,3 +1,8 @@
# Source version
ifndef OWLPS_VERSION
OWLPS_VERSION = $$(git describe)
endif
# Emplacement de la suite de cross-compilation # Emplacement de la suite de cross-compilation
TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09 TOOLCHAIN_PREFIX = $$HOME/openwrt/atheros/8.09
TOOLCHAIN_BIN = $(TOOLCHAIN_PREFIX)/staging_dir/toolchain-mips_gcc4.1.2/bin 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) LIBS = -lpcap -liw -lm $(LOWLPSCLIENTA)
LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib LATHEROS = -L$(TOOLCHAIN_USR)/lib -L$(TOOLCHAIN_USR_2)/lib
IATHEROS = -I$(TOOLCHAIN_USR)/include -I$(TOOLCHAIN_USR_2)/include 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 #OWLPSFLAGS += -D USE_CONFIG_FILE -lconfuse
LDFLAGS = $(OWLPSFLAGS) $(LIBS) LDFLAGS = $(OWLPSFLAGS) $(LIBS)

View File

@ -24,23 +24,25 @@
* version of glibc, or another libc (e.g. uClibc), we must define them * version of glibc, or another libc (e.g. uClibc), we must define them
* manually. * manually.
*/ */
#ifndef le32toh #if __BYTE_ORDER == __LITTLE_ENDIAN
# if __BYTE_ORDER == __LITTLE_ENDIAN # ifndef le32toh
# define le32toh(x) (x) # define le32toh(x) (x)
# else // __BYTE_ORDER == __LITTLE_ENDIAN # endif // le32toh
# include <byteswap.h> # ifndef le16toh
# define le32toh(x) bswap_32(x)
# endif // __BYTE_ORDER == __LITTLE_ENDIAN
#endif // le32toh
#ifndef le16toh
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define le16toh(x) (x) # define le16toh(x) (x)
# else // __BYTE_ORDER == __LITTLE_ENDIAN # endif // le16toh
# include <byteswap.h> #else // __BYTE_ORDER == __LITTLE_ENDIAN
# define le16toh(x) bswap_16(x) # if __BYTE_ORDER == __BIG_ENDIAN
# endif // __BYTE_ORDER == __LITTLE_ENDIAN # ifndef le32toh
#endif // le16toh # 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 */ /* 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 initialise_configuration(int argc, char **argv) ;
void parse_config_file(int argc, char **argv) ; void parse_config_file(int argc, char **argv) ;
void parse_command_line(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) ; void check_configuration(void) ;
#ifdef DEBUG #ifdef DEBUG
void print_configuration(void) ; void print_configuration(void) ;
@ -157,6 +161,22 @@ void print_version(void) ;
(cfg_setint(cfg, "autocalibration_nb_packets", (NBPKT))) (cfg_setint(cfg, "autocalibration_nb_packets", (NBPKT)))
#define GET_AUTOCALIBRATION_NBPKT() \ #define GET_AUTOCALIBRATION_NBPKT() \
(cfg_getint(cfg, "autocalibration_nb_packets")) (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 #endif // USE_PTHREAD
#define SET_VERBOSE() \ #define SET_VERBOSE() \
@ -234,6 +254,22 @@ void print_version(void) ;
(options.autocalibration_nb_packets = (NBPKT)) (options.autocalibration_nb_packets = (NBPKT))
#define GET_AUTOCALIBRATION_NBPKT() \ #define GET_AUTOCALIBRATION_NBPKT() \
(options.autocalibration_nb_packets) (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 #endif // USE_PTHREAD
#define SET_VERBOSE() \ #define SET_VERBOSE() \

View File

@ -28,6 +28,8 @@
#include <netinet/udp.h> #include <netinet/udp.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <assert.h>
char *program_name = NULL ; char *program_name = NULL ;
uint8_t my_mac_bytes[ETHER_ADDR_LEN] ; // AP MAC address 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 pcap_t *capture_handler = NULL ; // Packet capture descriptor
int aggregation_sockfd ; int aggregation_sockfd ;
struct sockaddr_in aggregation_server ; struct sockaddr_in aggregation_server ;
#ifdef USE_PTHREAD
int autocalibration_send_sockfd ; int autocalibration_send_sockfd ;
struct sockaddr_in autocalibration_send_server ; 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 #ifdef USE_CONFIG_FILE
cfg_t *cfg ; // Configuration structure cfg_t *cfg ; // Configuration structure
@ -64,6 +71,10 @@ struct {
uint_fast32_t autocalibration_hello_delay ; uint_fast32_t autocalibration_hello_delay ;
uint_fast32_t autocalibration_delay ; uint_fast32_t autocalibration_delay ;
uint_fast16_t autocalibration_nb_packets ; 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 #endif // USE_PTHREAD
owl_bool verbose ; owl_bool verbose ;
owl_bool display_captured ; owl_bool display_captured ;
@ -85,6 +96,7 @@ struct {
DEFAULT_AUTOCALIBRATION_HELLO_DELAY, DEFAULT_AUTOCALIBRATION_HELLO_DELAY,
DEFAULT_AUTOCALIBRATION_DELAY, DEFAULT_AUTOCALIBRATION_DELAY,
DEFAULT_AUTOCALIBRATION_NBPKT, DEFAULT_AUTOCALIBRATION_NBPKT,
0, 0, 0, 0,
#endif // USE_PTHREAD #endif // USE_PTHREAD
FALSE, FALSE,
FALSE FALSE
@ -278,6 +290,14 @@ void parse_config_file(int argc, char **argv)
// Number of packets for a calibration request: // Number of packets for a calibration request:
CFG_INT("autocalibration_nb_packets", CFG_INT("autocalibration_nb_packets",
DEFAULT_AUTOCALIBRATION_NBPKT, CFGF_NONE), 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 #endif // USE_PTHREAD
// Be verbose, or not: // Be verbose, or not:
CFG_BOOL("verbose", cfg_false, CFGF_NONE), 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," " You must specify all options on the command line,"
" or default value will be used.\n") ; " or default value will be used.\n") ;
#endif // USE_CONFIG_FILE #endif // USE_CONFIG_FILE
break ;
case 'h' : case 'h' :
print_usage() ; print_usage() ;
exit(0) ; exit(0) ;
@ -347,6 +368,14 @@ void parse_config_file(int argc, char **argv)
void parse_command_line(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 ; 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() void check_configuration()
{ {
switch (GET_MODE()) switch (GET_MODE())
@ -481,15 +533,6 @@ void check_configuration()
SET_WIFI_IFACE(GET_RTAP_IFACE()) ; 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 // // Port numbers //
if (GET_AGGREGATION_PORT() < 1 || GET_AGGREGATION_PORT() > 65535) if (GET_AGGREGATION_PORT() < 1 || GET_AGGREGATION_PORT() > 65535)
{ {
@ -505,22 +548,49 @@ void check_configuration()
" failing back to the default value.\n") ; " failing back to the default value.\n") ;
SET_LISTENING_PORT(LOC_REQUEST_DEFAULT_PORT) ; 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()) if (GET_AUTOCALIBRATION_IP()[0] == '\0')
fprintf(stderr, "Warning! Bad autocalibration_request_port:" {
" failing back to the default value.\n") ; if (GET_VERBOSE())
SET_AUTOCALIBRATION_REQUEST_PORT(DEFAULT_AUTOCALIBRATION_REQUEST_PORT) ; fprintf(stderr, "No autocalibration IP specified, we will"
} " use the aggregation IP as the destination of"
if (GET_AUTOCALIBRATION_PORT() < 1 || " autocalibration requests.\n") ;
GET_AUTOCALIBRATION_PORT() > 65535) SET_AUTOCALIBRATION_IP(GET_AGGREGATION_IP()) ;
{ }
if (GET_VERBOSE())
fprintf(stderr, "Warning! Bad autocalibration_port:" if (GET_AUTOCALIBRATION_NBPKT() < 1)
" failing back to the default value.\n") ; fprintf(stderr, "Warning! autocalibration_nb_packets is null,"
SET_AUTOCALIBRATION_PORT(DEFAULT_AUTOCALIBRATION_PORT) ; " 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_hello_delay = %"PRIuFAST32"\n"
"autocalibration_delay = %"PRIuFAST32"\n" "autocalibration_delay = %"PRIuFAST32"\n"
"autocalibration_nb_packets = %"PRIuFAST16"\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 #endif // USE_PTHREAD
"verbose = %s\n" "verbose = %s\n"
"display_captured = %s\n" "display_captured = %s\n"
@ -567,6 +641,10 @@ void print_configuration()
GET_AUTOCALIBRATION_HELLO_DELAY(), GET_AUTOCALIBRATION_HELLO_DELAY(),
GET_AUTOCALIBRATION_DELAY(), GET_AUTOCALIBRATION_DELAY(),
GET_AUTOCALIBRATION_NBPKT(), GET_AUTOCALIBRATION_NBPKT(),
GET_MY_DIRECTION(),
GET_MY_POSITION_X(),
GET_MY_POSITION_Y(),
GET_MY_POSITION_Z(),
#endif // USE_PTHREAD #endif // USE_PTHREAD
OWL_BOOL_TO_STRING(GET_VERBOSE()), OWL_BOOL_TO_STRING(GET_VERBOSE()),
OWL_BOOL_TO_STRING(GET_DISPLAY_CAPTURED()) 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!") ; printf(".. on the wrong port!") ;
putchar('\n') ; 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 ; break ;
default : default :
@ -973,9 +1066,9 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
request_time_str, request_time_str,
start_time_str, start_time_str,
request.antenna_signal_dbm - 0x100, request.antenna_signal_dbm - 0x100,
request.x_position, owl_ntohf(request.x_position),
request.y_position, owl_ntohf(request.y_position),
request.z_position, owl_ntohf(request.z_position),
request.direction request.direction
) ; ) ;
} }
@ -1172,7 +1265,12 @@ uint_fast16_t make_packet(uint8_t **packet)
{ {
uint8_t *pkt ; uint8_t *pkt ;
uint_fast16_t size ; // Packet size uint_fast16_t size ; // Packet size
uint_fast16_t offset ; // Index used to create the packet
owl_timestamp request_time ; 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) ; owl_timestamp_now(&request_time) ;
@ -1185,11 +1283,29 @@ uint_fast16_t make_packet(uint8_t **packet)
request_time = owl_hton_timestamp(request_time) ; 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) ; pkt = malloc(size) ;
memset(&pkt[0], OWL_REQUEST_AUTOCALIBRATION, 1) ; // Packet type // Request type:
memcpy(&pkt[1], &request_time, sizeof(request_time)) ; 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 ; *packet = pkt ;
return size ; return size ;
@ -1225,13 +1341,13 @@ void print_usage()
" [-D autocalibration_ip]" " [-D autocalibration_ip]"
" [-P autocalibration_request_port ] [-a autocalibration_port]" " [-P autocalibration_request_port ] [-a autocalibration_port]"
" [-H autocalibration_hello_delay] [-t autocalibration_delay]" " [-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 -h\n"
"\t%s -V\n" "\t%s -V\n"
"Main options:\n" "Main options:\n"
"\t-h\t\tPrint this help.\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" "\t-f config_file\tUse 'config_file' instead of the default"
" configuration file (%s). Available only if program was" " configuration file (%s). Available only if program was"
" compiled with libconfuse.\n" " compiled with libconfuse.\n"
@ -1255,16 +1371,19 @@ void print_usage()
"\t-A\t\t\tEnable autocalibration (default: disabled).\n" "\t-A\t\t\tEnable autocalibration (default: disabled).\n"
"\t-D autocalib_ip\t\tDestination IP of the autocalibration" "\t-D autocalib_ip\t\tDestination IP of the autocalibration"
"requests (default: aggregation_ip).\n" "requests (default: aggregation_ip).\n"
"\t-P autocalib_req_port\tPort on which autocalibration positioning" "\t-P autocalib_req_port\tPort on which autocalibration"
" requests are sent (default: %d).\n" " positioning requests are sent (default: %d).\n"
"\t-a autocalib_port\tPort on which autocalibration data (hello & orders)" "\t-a autocalib_port\tPort on which autocalibration data (hello"
" are exchanged with the aggregation server (default: %d).\n" " & orders) are exchanged with the aggregation server"
" (default: %d).\n"
"\t-H hello_delay\t\tTime between each hello" "\t-H hello_delay\t\tTime between each hello"
" message sent to the aggregation server (default: %d s).\n" " message sent to the aggregation server (default: %d s).\n"
"\t-t delay\t\tTime between each autocalibration" "\t-t delay\t\tTime between each autocalibration"
" packet transmission (default: %d µs).\n" " packet transmission (default: %d µs).\n"
"\t-n nb_packets\t\tNumber of packet transmitted" "\t-n nb_packets\t\tNumber of packet transmitted"
" for one autocalibration request (default: %d).\n" " 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" "Other options:\n"
"\t-k\tKeep the monitor mode up on wifi_iface. Use it with buggy" "\t-k\tKeep the monitor mode up on wifi_iface. Use it with buggy"
@ -1293,12 +1412,18 @@ void print_usage()
void print_version() 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" " System project.\n"
"\n" "Version: %s.\n"
"Compilation-time options:\n" "Compilation-time options:\n"
"\tSupport for POSIX threads: %s.\n" "\tSupport for POSIX threads: %s.\n"
"\tSupport for configuration file (libconfuse): %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 #ifdef USE_PTHREAD
"YES" "YES"
#else // USE_PTHREAD #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 SRC_DIR = src
OBJ_DIR = obj OBJ_DIR = obj
TESTS_DIR = tests TESTS_DIR = tests
@ -8,7 +12,7 @@ DOXYFILE = Doxyfile
# Installation directory # Installation directory
PREFIX = /usr/local PREFIX = /usr/local
INSTALL_DIR = $(PREFIX)/bin INSTALL_DIR = $(PREFIX)/bin
# System tools # System tools
RM = rm -fv RM = rm -fv
@ -19,7 +23,7 @@ MKDIR = mkdir -pv
# Other tools # Other tools
STYLE = astyle --style=gnu --formatted STYLE = astyle --style=gnu --formatted
CPPCHECK = cppcheck --enable=all CPPCHECK = cppcheck --quiet --enable=all
DOXYGEN = doxygen >/dev/null DOXYGEN = doxygen >/dev/null
# Compilation tools # Compilation tools
@ -36,8 +40,11 @@ GXXFLAGS = $(DEBUG) -Wall -Wextra -I$(LIBOWLPS_DIR)
LD = $(CXX) LD = $(CXX)
LDFLAGS = -lstdc++ -lm -lrt -lboost_program_options \ LDFLAGS = -lstdc++ -lm -lrt -lboost_program_options \
-L$(LIBOWLPS_DIR) -lowlps -L$(LIBOWLPS_DIR) -lowlps
OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\"
# Targets # Targets
.PHONY : all test doc clean purge install uninstall style check
TARGET = owlps-positioning TARGET = owlps-positioning
OBJ_TARGET = $(OBJ_DIR)/$(TARGET).o OBJ_TARGET = $(OBJ_DIR)/$(TARGET).o
SOURCE_TARGET = $(SRC_DIR)/$(TARGET).cc 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) OBJ_TESTS = $(TESTUTIL_OBJ) $(TESTSETUP_OBJ)
INCLUDES_TESTS = $(TESTS_DIR)/valuetraits.hh INCLUDES_TESTS = $(TESTS_DIR)/valuetraits.hh
all: prepare $(TARGET) all: $(TARGET)
# Generic targets # Generic targets
$(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cc $(TESTS_DIR)/%.hh $(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cc $(TESTS_DIR)/%.hh
$(CXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $< $(CXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh
$(CXX) $(GXXFLAGS) -o $@ -c $< $(MKDIR) $(OBJ_DIR) && $(CXX) $(GXXFLAGS) $(OWLPSFLAGS) -o $@ -c $<
%: $(OBJ_DIR)/%.o %: $(OBJ_DIR)/%.o
$(LD) $(LDFLAGS) -o $@ $^ $(LD) $(LDFLAGS) -o $@ $^
@ -289,15 +296,12 @@ $(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
$(TESTS_TARGET): $(TESTS_OBJ) $(OBJ_TESTS) $(OBJ) $(OBJ_NOTEST) $(TESTS_TARGET): $(TESTS_OBJ) $(OBJ_TESTS) $(OBJ) $(OBJ_NOTEST)
$(LD) $(LDFLAGS) -o $@ $^ $(LD) $(LDFLAGS) -o $@ $^
test: prepare $(TESTS_TARGET) test: $(TESTS_TARGET)
@$(TESTS_TARGET) @$(TESTS_TARGET)
doc: doc:
@$(DOXYGEN) $(DOXYFILE) @$(DOXYGEN) $(DOXYFILE)
prepare:
@$(MKDIR) $(OBJ_DIR)
clean: clean:
@$(RM) *~ */*~ *.orig */*.orig @$(RM) *~ */*~ *.orig */*.orig
@$(RM_RECURSIVE_VERBOSE) $(OBJ_DIR) @$(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? - Write a class for Request::type?
CalibrationRequest::direction uses a dedicated class Direction, why CalibrationRequest::direction uses a dedicated class Direction, why
not Request::type? That would simplify writing of the type to not Request::type? That would simplify writing of the type to
@ -38,9 +35,6 @@
° Différencier le pas pour X, Y et Z ? ° Différencier le pas pour X, Y et Z ?
° Régler le start & stop dans MultilaterationAlgorithm. ° Régler le start & stop dans MultilaterationAlgorithm.
- Mobile
Attributs Viterbi ? (Cf. l'ancien clientinfo.hh.)
- Renommages de membres - Renommages de membres
° InputMedium : ° InputMedium :
°° current_line_nb et get_current_line_nb() °° current_line_nb et get_current_line_nb()
@ -48,10 +42,6 @@
° Input : get_next_request() > read_next_request() ° Input : get_next_request() > read_next_request()
° Area : p_min et p_max > coord_min et coord_max ° 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 » - « C++ en action »
° Espaces de noms ? 109 ° Espaces de noms ? 109
° Réserver l'espace mémoire des vector avec reserve(). 217 ° 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 cerr
<< "Bad value « " << "Bad value « "

View File

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

View File

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

View File

@ -1,53 +1,15 @@
#include "outputcsv.hh" #include "outputcsv.hh"
#include "request.hh"
#include "resultlist.hh" #include "resultlist.hh"
#include "mobile.hh"
#include <sstream>
using namespace std ;
/* *** Operations *** */ void OutputCSV::write(const Result &result)
const string OutputCSV::result_to_csv(const Result &result)
{ {
ostringstream csv_line ; file.write_text(result.to_csv() + '\n') ;
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() ;
} }
const string OutputCSV::results_to_csv(const ResultList &results) void OutputCSV::write(const ResultList &results)
{ {
ostringstream csv_line ; file.write_text(results.to_csv() + '\n') ;
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() ;
} }

View File

@ -14,9 +14,6 @@ class OutputCSV: public OutputMedium
protected: protected:
TextFileWriter file ; TextFileWriter file ;
const std::string result_to_csv(const Result &result) ;
const std::string results_to_csv(const ResultList &results) ;
public: public:
OutputCSV(const std::string &filename): OutputCSV(const std::string &filename):
file(filename) {} file(filename) {}
@ -30,17 +27,5 @@ public:
/* *** Operations *** */ /* *** 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_ #endif // _OWLPS_POSITIONING_OUTPUTCSV_HH_

View File

@ -1,18 +1,15 @@
#include "outputudpsocket.hh" #include "outputudpsocket.hh"
#include "request.hh" #include "request.hh"
#include "resultlist.hh" #include "resultlist.hh"
#include "posexcept.hh"
#include <owlps.h>
#include <sstream> #include <sstream>
#include <iostream> #include <cstdio> // For perror()
#include <netdb.h>
#include <cstring>
using namespace std ; using namespace std ;
struct hostent *hostInfo ;
struct sockaddr_in serverAddress ;
/* *** Constructors *** */ /* *** Constructors *** */
@ -22,13 +19,15 @@ OutputUDPSocket::OutputUDPSocket(const string &_remote_host,
const uint_fast16_t _remote_port): const uint_fast16_t _remote_port):
remote_host(_remote_host), remote_port(_remote_port) remote_host(_remote_host), remote_port(_remote_port)
{ {
init_socket() ; if (! init_socket())
throw error_opening_output_file("UDP socket") ;
} }
OutputUDPSocket::~OutputUDPSocket() OutputUDPSocket::~OutputUDPSocket()
{ {
kill_socket() ; close_socket() ;
} }
@ -36,56 +35,63 @@ OutputUDPSocket::~OutputUDPSocket()
/* *** Operations *** */ /* *** 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) void OutputUDPSocket::write(const Result &result)
{ {
string timestampXYZ; send_data(result.to_csv()) ;
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);
} }
void OutputUDPSocket::init_socket() void OutputUDPSocket::write(const ResultList &results)
{ {
cout << "Initialisation socket..." << endl; send_data(results.to_csv()) ;
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);
} }
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, ssize_t nsent = sendto(sockfd, data.c_str(), data.size(), 0,
(struct sockaddr *) &serverAddress, (struct sockaddr *) &server_info,
sizeof(serverAddress)) < 0) sizeof(server_info)) ;
{ if (nsent != static_cast<ssize_t>(data.size()))
cerr << "Émission du message impossible\n"; perror("Error sending result data") ;
close(socketDescriptor);
}
}
void OutputUDPSocket::kill_socket()
{
cout << "Fermeture de la socket..." << endl;
close(socketDescriptor);
} }

View File

@ -5,21 +5,28 @@
#include <string> #include <string>
#include <stdint.h> // <cstdint> is not C++ 98 compliant #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 class OutputUDPSocket: public OutputMedium
{ {
private: protected:
int socketDescriptor ; int sockfd ;
std::string remote_host ; std::string remote_host ;
uint_fast16_t remote_port ; uint_fast16_t remote_port ;
struct sockaddr_in server_info ;
struct sockaddr_in client_info ;
/** @name Operations */ /** @name Operations */
//@{ //@{
/// Initialises the socket /// Initialises the socket
void init_socket(void) ; bool init_socket(void) ;
void kill_socket(void) ; void send_data(const std::string &data) ;
void send_data(std::string msg) ;
//@} //@}
public: public:
@ -29,9 +36,10 @@ public:
/** @name Operations */ /** @name Operations */
//@{ //@{
/// Initialises the socket
void write(const Result &result) ; void write(const Result &result) ;
void write(const ResultList &results) ; void write(const ResultList &results) ;
/// Closes the socket
bool close_socket(void) ;
//@} //@}
} ; } ;

View File

@ -1,6 +1,10 @@
#include "result.hh" #include "result.hh"
#include "request.hh" #include "request.hh"
#include <sstream>
using namespace std ;
/* *** Operators *** */ /* *** 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 os
<< "The result of the algorithm " << r.algorithm << "The result of the algorithm " << r.algorithm

View File

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

View File

@ -1,5 +1,8 @@
#include "resultlist.hh" #include "resultlist.hh"
#include "request.hh" #include "request.hh"
#include "mobile.hh"
#include <sstream>
using namespace std ; 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) ostream& operator<<(ostream &os, const ResultList &r)
{ {
if (r.request == NULL) if (r.request == NULL)

View File

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

View File

@ -1,6 +1,8 @@
#include "textfilereader.hh" #include "textfilereader.hh"
#include "posexcept.hh" #include "posexcept.hh"
#include <iostream>
using namespace std ; using namespace std ;
@ -15,15 +17,26 @@ using namespace std ;
TextFileReader::TextFileReader(const string &_file_name): TextFileReader::TextFileReader(const string &_file_name):
file_name(_file_name), current_line_nb(0) file_name(_file_name), current_line_nb(0)
{ {
file.open(file_name.c_str()) ; if (file_name == "-")
if (! file) {
throw error_opening_input_file(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() 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 <string>
#include <fstream> #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 class TextFileReader
{ {
protected: protected:
/// Name of the input file
std::string file_name ; std::string file_name ;
/// Stream associated with the file
std::ifstream file ; std::ifstream file ;
/// Original rdbuf of the stream
std::streambuf *file_buf ;
/// Number of the last line read
unsigned int current_line_nb ; unsigned int current_line_nb ;
/// Checks if the file is readable and closes it if not /// Checks if the file is readable and closes it if not

View File

@ -2,6 +2,8 @@
#include "configuration.hh" #include "configuration.hh"
#include "posexcept.hh" #include "posexcept.hh"
#include <iostream>
using namespace std ; 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. * @throw error_opening_input_file if the file cannot be opened.
*/ */
TextFileWriter::TextFileWriter(const string &_file_name): TextFileWriter::TextFileWriter(const string &_file_name):
file_name(_file_name) file_name(_file_name)
{ {
file.open(file_name.c_str()) ; if (file_name == "-")
if (! file) {
throw error_opening_output_file(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() 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 <string>
#include <fstream> #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 class TextFileWriter
{ {
private: private:
/// Name of the output file
std::string file_name ; std::string file_name ;
/// Stream associated with the file
std::ofstream file ; std::ofstream file ;
/// Original rdbuf of the stream
std::streambuf *file_buf ;
public: public:
TextFileWriter(const std::string &_file_name) ; TextFileWriter(const std::string &_file_name) ;

View File

@ -72,10 +72,11 @@ void UserInterface::fill_options()
void UserInterface::fill_cli_options() void UserInterface::fill_cli_options()
{ {
cli_options->add_options() cli_options->add_options()
("help,h", "Print help") ("help,h", "Print help.")
("version,V", "Print version information.")
("config-file,f", po::value<string>() ("config-file,f", po::value<string>()
->default_value(DEFAULT_CONFIG_FILE_NAME), ->default_value(DEFAULT_CONFIG_FILE_NAME),
"Alternative configuration file") "Alternative configuration file.")
; // End of options ; // 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.") If this option is absent, results will be printed on the terminal.")
("output.csv-file", po::value<string>(), ("output.csv-file", po::value<string>(),
"CSV file to use for output (when output.medium = CSV).") "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).") "Host to which the UDP data is sent (when output.medium = UDP).")
("output.udp-port", po::value<int>() ("output.udp-port", po::value<int>()
->default_value(MOBILE_DEFAULT_PORT), ->default_value(MOBILE_DEFAULT_PORT),
@ -214,7 +215,7 @@ void UserInterface::fill_misc_options()
void UserInterface::parse_options() void UserInterface::parse_options()
{ {
parse_command_line() ; parse_command_line() ;
print_usage_and_exit_if_requested() ; print_information_and_exit_if_requested() ;
parse_file() ; 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")) if (Configuration::is_configured("help"))
{ {
cout << *cli_options ; 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_command_line(void) const ;
void parse_file(void) const ; void parse_file(void) const ;
/// If help was requested by user, displays accepted options and exit /// Print usage and/or version information if requested by the user
void print_usage_and_exit_if_requested(void) const ; void print_information_and_exit_if_requested(void) const ;
//@} //@}
public: 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 ; ostringstream csv ;
csv << (Point3D) *this ; csv << (Point3D) *this ;