Merge branch 'dev' into dev-drone
- Fix send calibration message. - Update makefile to add version.
This commit is contained in:
commit
e45c199130
26
TODO
26
TODO
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
) ;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
) ;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ##
|
||||
|
|
|
@ -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 ##
|
||||
|
|
|
@ -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
|
||||
) ;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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() \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -117,7 +117,7 @@ bool CSVFileReader::read_point3d(Point3D &p)
|
|||
}
|
||||
|
||||
|
||||
void CSVFileReader::print_error_cast()
|
||||
void CSVFileReader::print_error_cast() const
|
||||
{
|
||||
cerr
|
||||
<< "Bad value « "
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) ;
|
||||
|
|
|
@ -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') ;
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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") ;
|
||||
}
|
||||
|
|
|
@ -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) ;
|
||||
//@}
|
||||
} ;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) ;
|
||||
} ;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) ;
|
||||
|
|
|
@ -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() ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) ;
|
||||
|
|
|
@ -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) ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 ;
|
||||
|
|
Loading…
Reference in New Issue