From de742131028a5b26202c8ed647522b3d2ff6979e Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 18 Aug 2011 14:02:17 +0200 Subject: [PATCH 01/46] [lib] Rename OWL_TIMESTAMP_STR_LEN OWL_TIMESTAMP_STRLEN --- libowlps/libowlps.c | 4 ++-- libowlps/owlps.h | 2 +- owlps-aggregator/owlps-aggregatord.c | 10 +++++----- owlps-client/owlps-client.c | 2 +- owlps-listener/owlps-listenerd.c | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libowlps/libowlps.c b/libowlps/libowlps.c index aaa0881..9b0e1b8 100644 --- a/libowlps/libowlps.c +++ b/libowlps/libowlps.c @@ -200,12 +200,12 @@ uint64_t owl_timestamp_to_ms(const owl_timestamp d) /* * 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_STRLEN * characters. */ void owl_timestamp_to_string(char *const dst, const owl_timestamp src) { - snprintf(dst, OWL_TIMESTAMP_STR_LEN, "%"PRIu32".%"PRIu32, + snprintf(dst, OWL_TIMESTAMP_STRLEN, "%"PRIu32".%"PRIu32, src.tv_sec, src.tv_nsec) ; } diff --git a/libowlps/owlps.h b/libowlps/owlps.h index 40bd0ba..7759248 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -53,7 +53,7 @@ typedef struct _owl_timestamp uint32_t tv_nsec ; } owl_timestamp ; // Length of a owl_timestamp when converted to string: -#define OWL_TIMESTAMP_STR_LEN 22 // 22 = 10 digits, '.', 10 digits, '\0' +#define OWL_TIMESTAMP_STRLEN 22 // 22 = 10 digits, '.', 10 digits, '\0' /* Message sent by the listener to the aggregator */ diff --git a/owlps-aggregator/owlps-aggregatord.c b/owlps-aggregator/owlps-aggregatord.c index 7047e3f..efa9be5 100644 --- a/owlps-aggregator/owlps-aggregatord.c +++ b/owlps-aggregator/owlps-aggregatord.c @@ -422,8 +422,8 @@ int read_loop(int sockfd) char // Return values of mobile_ip_str[INET_ADDRSTRLEN], // inet_ntop() // and owl_timestamp_to_string(): - request_time_str[OWL_TIMESTAMP_STR_LEN], - start_time_str[OWL_TIMESTAMP_STR_LEN] ; + request_time_str[OWL_TIMESTAMP_STRLEN], + start_time_str[OWL_TIMESTAMP_STRLEN] ; while (owl_run) { @@ -506,7 +506,7 @@ void* monitor_requests(void *NULL_value) FILE *fd = NULL ; char mac_str[OWL_ETHER_ADDR_STRLEN] ; uint_fast32_t sub ; // owl_time_elapsed_ms() result - char request_time_str[OWL_TIMESTAMP_STR_LEN] ; + char request_time_str[OWL_TIMESTAMP_STRLEN] ; uint_fast32_t aggregate_timeout = cfg_getint(cfg, "aggregate_timeout") ; @@ -1191,8 +1191,8 @@ void print_request_list() request_info_list *info_ptr = NULL ; char mobile_mac_str[OWL_ETHER_ADDR_STRLEN] ; char - request_time_str[OWL_TIMESTAMP_STR_LEN], - start_time_str[OWL_TIMESTAMP_STR_LEN] ; + request_time_str[OWL_TIMESTAMP_STRLEN], + start_time_str[OWL_TIMESTAMP_STRLEN] ; sem_wait(&lock_requests) ; diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 2fc95d0..95ca65d 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -373,7 +373,7 @@ void make_packet() { uint_fast16_t offset ; // Index used to create the packet owl_timestamp request_time ; - char request_time_str[OWL_TIMESTAMP_STR_LEN] ; + char request_time_str[OWL_TIMESTAMP_STRLEN] ; // Get the current time and copy it as a string before to switch it to // network endianess: diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 56e0033..4e0e8d9 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -977,8 +977,8 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, if (GET_DISPLAY_CAPTURED()) { char - request_time_str[OWL_TIMESTAMP_STR_LEN], - start_time_str[OWL_TIMESTAMP_STR_LEN] ; + request_time_str[OWL_TIMESTAMP_STRLEN], + start_time_str[OWL_TIMESTAMP_STRLEN] ; owl_timestamp_to_string(request_time_str, owl_ntoh_timestamp(request.request_time)) ; owl_timestamp_to_string(start_time_str, @@ -1332,7 +1332,7 @@ uint_fast16_t make_packet(uint8_t **packet) if (VERBOSE_CHATTERBOX) { - char request_time_str[OWL_TIMESTAMP_STR_LEN] ; + char request_time_str[OWL_TIMESTAMP_STRLEN] ; owl_timestamp_to_string(request_time_str, request_time) ; printf("Autocalibration time: %s\n", request_time_str) ; } From c61c4b3a2253892632a0440762a1306464e0b35b Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 18 Aug 2011 21:36:42 +0200 Subject: [PATCH 02/46] [Positioning] UDP & TCPEvAAL: send '\0' Send the final null character of the CSV string. --- owlps-positioning/src/outputtcpsocketevaal.cc | 5 +++-- owlps-positioning/src/outputudpsocket.cc | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/owlps-positioning/src/outputtcpsocketevaal.cc b/owlps-positioning/src/outputtcpsocketevaal.cc index 68b0d24..ebec47e 100644 --- a/owlps-positioning/src/outputtcpsocketevaal.cc +++ b/owlps-positioning/src/outputtcpsocketevaal.cc @@ -123,8 +123,9 @@ area_of_interest_number(const Point3D &position) const */ bool OutputTCPSocketEvAAL::send_data(const string &data) const { - ssize_t nsent = send(sockfd, data.c_str(), data.size(), 0) ; - if (nsent != static_cast(data.size())) + unsigned int data_len = data.size() + 1 ; // +1 for the '\0' + ssize_t nsent = send(sockfd, data.c_str(), data_len, 0) ; + if (nsent != static_cast(data_len)) { perror("Error sending result data through the TCPEvAAL socket") ; return false ; diff --git a/owlps-positioning/src/outputudpsocket.cc b/owlps-positioning/src/outputudpsocket.cc index ebc8350..1984e04 100644 --- a/owlps-positioning/src/outputudpsocket.cc +++ b/owlps-positioning/src/outputudpsocket.cc @@ -45,10 +45,11 @@ bool OutputUDPSocket::init_socket() */ bool OutputUDPSocket::send_data(const string &data) const { - ssize_t nsent = sendto(sockfd, data.c_str(), data.size(), 0, + unsigned int data_len = data.size() + 1 ; // +1 for the '\0' + ssize_t nsent = sendto(sockfd, data.c_str(), data_len, 0, (struct sockaddr *) &server_info, sizeof(server_info)) ; - if (nsent != static_cast(data.size())) + if (nsent != static_cast(data_len)) { perror("Error sending result data through the UDP socket") ; return false ; From 084daed33f55e4913a62639186eafedea2a487f7 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Thu, 18 Aug 2011 23:10:49 +0200 Subject: [PATCH 03/46] Add libowlps-resultreader-udp This new library is to help external programs to receive and interpret results sent by OwlPS Positioning through an UDP socket. --- Makefile | 6 + libowlps-resultreader-udp/Makefile | 81 ++++++ .../libowlps-resultreader-udp.c | 267 ++++++++++++++++++ .../owlps-resultreader-udp.c | 34 +++ .../owlps-resultreader-udp.h | 70 +++++ libowlps/owlps.h | 4 + 6 files changed, 462 insertions(+) create mode 100644 libowlps-resultreader-udp/Makefile create mode 100644 libowlps-resultreader-udp/libowlps-resultreader-udp.c create mode 100644 libowlps-resultreader-udp/owlps-resultreader-udp.c create mode 100644 libowlps-resultreader-udp/owlps-resultreader-udp.h diff --git a/Makefile b/Makefile index 037415e..51d916b 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ all c clean purge help \ libowlps \ libowlps-client \ + libowlps-resultreader-udp \ owlps-client \ owlps-listener \ owlps-aggregator \ @@ -26,6 +27,7 @@ all: \ c: \ libowlps \ libowlps-client \ + libowlps-resultreader-udp \ owlps-client \ owlps-listener \ owlps-aggregator @@ -34,6 +36,8 @@ libowlps: @make -C $@ libowlps-client: libowlps @make -C $@ +libowlps-resultreader-udp: libowlps + @make -C $@ owlps-client: libowlps libowlps-client @make -C $@ owlps-listener: libowlps libowlps-client @@ -91,6 +95,7 @@ uninstall-owlps-positioning: clean : @make -C libowlps clean @make -C libowlps-client clean + @make -C libowlps-resultreader-udp clean @make -C owlps-client clean @make -C owlps-listener clean @make -C owlps-aggregator clean @@ -99,6 +104,7 @@ clean : purge : @make -C libowlps purge @make -C libowlps-client purge + @make -C libowlps-resultreader-udp purge @make -C owlps-client purge @make -C owlps-listener purge @make -C owlps-aggregator purge diff --git a/libowlps-resultreader-udp/Makefile b/libowlps-resultreader-udp/Makefile new file mode 100644 index 0000000..21213a4 --- /dev/null +++ b/libowlps-resultreader-udp/Makefile @@ -0,0 +1,81 @@ +# Compilateur +COLORGCC := $(shell which colorgcc >/dev/null 2>&1 ; echo $$?) +ifeq ($(COLORGCC), 0) + CC = colorgcc +endif + +# Autres outils +AR = ar +RANLIB = ranlib +RM = rm -f + +# Variables générales +LIB_CIBLE = libowlps-resultreader-udp +VERSION = 1.0 + +# Cibles à construire +STATIC = $(LIB_CIBLE).a +HEADER = owlps-resultreader-udp.h +EXAMPLE = owlps-resultreader-udp + +# Composition de la bibliothèque +OBJS = $(LIB_CIBLE).o + +# Flags +LIBOWLPS_DIR = ../libowlps +CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +CFLAGS += -D DEBUG +DEPFLAGS = -MMD +XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) +PICFLAG = -fPIC +#STRIPFLAGS = -Wl,-s +#LDFLAGS = + + +## Cibles de compilation standard ## + +.PHONY : all static clean purge help + +all : static example +static : $(STATIC) +example : $(EXAMPLE) + +# Cancel implicit make rule +%: %.c + +%.o : %.c $(HEADER) + $(CC) $(XCFLAGS) -c $< + +% : %.o $(HEADER) $(STATIC) + $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $< \ + $(STATIC) -L$(LIBOWLPS_DIR) -lowlps -lrt + +# Compilation de la bibliothèque statique +$(STATIC) : $(OBJS) + $(RM) $@ + $(AR) cru $@ $^ + $(RANLIB) $@ + + +## Nettoyage ## + +clean : + @$(RM) *~ *.o *.d + +purge : clean + @$(RM) $(STATIC) $(EXAMPLE) + + +## Aide ## + +help : + @echo "Bibliothèques nécessaires à la compilation :" + @echo " libowlps-dev" + @echo + @echo "Cibles possibles :" + @echo " static : Compile la bibliothèque statique (.a)." + @echo " example : Compile le programme d'exemple." + @echo " (Cible par défaut : static et example.)" + @echo + @echo " clean : Supprime les fichiers temporaires." + @echo " purge : Supprime le résultat de la compilation." diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c new file mode 100644 index 0000000..bd09ba6 --- /dev/null +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -0,0 +1,267 @@ +#include "owlps-resultreader-udp.h" + +#include +#include +#include + + +#define CSV_DELIMITER ";" + + +/* + * Receives a result from the socket of file descriptor 'sockfd' and + * fills an owl_result structure 'result'. + * + * Note that *result will be set by this function, and **result will + * point on a valid owl_result structure if everything goes well. + * You will have to free *result yourself with owl_free_result(). + * + * In case of error, *result is set to NULL. + */ +void owl_receive_position(int sockfd, owl_result **result) +{ + ssize_t nread ; // recvfrom return value + char csv[OWL_CSV_RESULT_STRLEN] ; // Read string + + nread = recvfrom(sockfd, &csv, OWL_CSV_RESULT_STRLEN, + 0, NULL, NULL) ; + + if (nread <= 0) + { + perror("No request received from listener") ; + *result = NULL ; + return ; + } + + owl_fill_result(result, csv) ; +} + + +/* Splits the 'csv' string received from OwlPS Positioning and stores + * the fields in 'result' (which is allocated). + * + * Handled CSV format: + * Mobile_MAC;Request_type;Request_timestamp;Algorithm;X;Y;Z;Error;Area + * The Request_timestamp format is: + * seconds.nanoseconds + */ +void owl_fill_result(owl_result **result, char *csv) +{ + char *csv_field = NULL ; + int nb_algorithms = 0 ; + owl_algorithm_result *current_algo = NULL ; + + *result = malloc(sizeof(owl_result)) ; + (*result)->results = NULL ; + + /* Mobile MAC address */ + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the mobile's MAC address from the CSV" + " string (empty string?)!\n") ; + goto error ; + } + (*result)->mobile_mac_addr = + strndup(csv_field, OWL_ETHER_ADDR_STRLEN) ; + + /* Request type */ + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the request type from the CSV string!\n") ; + goto error ; + } + (*result)->request_type = atoi(csv_field) ; + + /* Timestamp */ + // Seconds + csv_field = strsep(&csv, ".") ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the timestamp (seconds) from the CSV" + " string!\n") ; + goto error ; + } + (*result)->mobile_timestamp.tv_sec = atol(csv_field) ; + // Nanoseconds + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the timestamp (nanoseconds) from the CSV" + " string!\n") ; + goto error ; + } + (*result)->mobile_timestamp.tv_nsec = atol(csv_field) ; + + /* Algorithm results */ + csv_field = strsep(&csv, CSV_DELIMITER) ; + do + { + ++nb_algorithms ; + current_algo = malloc(sizeof(owl_algorithm_result)) ; + + // Algorithm name + if (! csv_field) + { + fprintf(stderr, + "Error reading the algorithm name from the CSV" + " string (algorithm #%d)!\n", nb_algorithms) ; + goto error ; + } + current_algo->algorithm = + strndup(csv_field, OWL_ALGORITHM_STRLEN) ; + + // X coordinate + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the X coordinate from the CSV" + " string (algorithm #%d)!\n", nb_algorithms) ; + goto error ; + } + current_algo->x = atof(csv_field) ; + + // Y coordinate + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the Y coordinate from the CSV" + " string (algorithm #%d)!\n", nb_algorithms) ; + goto error ; + } + current_algo->y = atof(csv_field) ; + + // Z coordinate + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the Z coordinate from the CSV" + " string (algorithm #%d)!\n", nb_algorithms) ; + goto error ; + } + current_algo->z = atof(csv_field) ; + + // Distance error + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the distance error from the CSV" + " string (algorithm #%d)!\n", nb_algorithms) ; + goto error ; + } + current_algo->error = atof(csv_field) ; + + // Area name (optional) + csv_field = strsep(&csv, CSV_DELIMITER) ; + if (csv_field) + current_algo->area = strndup(csv_field, OWL_AREA_STRLEN) ; + + // Insert the current algorithm at the begining of the list + current_algo->next = (*result)->results ; + (*result)->results = current_algo ; + } + while ((csv_field = strsep(&csv, CSV_DELIMITER))) ; + + return ; // Success + + error: + owl_free_result(*result) ; + *result = NULL ; + free(current_algo) ; +} + + +/* + * Prints an owl_result to the given stream. + */ +void owl_fprint_result(FILE *stream, owl_result *result) +{ + char timestamp_str[OWL_TIMESTAMP_STRLEN] ; + owl_timestamp_to_string(timestamp_str, result->mobile_timestamp) ; + + fprintf(stream, + "Mobile MAC: %s\n" + "Request type: %"PRIu8"\n" + "Mobile timestamp: %s\n" + "Results:\n" + , + result->mobile_mac_addr, + result->request_type, + timestamp_str + ) ; + + owl_algorithm_result *algo = result->results ; + while (algo) + { + owl_fprint_algorithm_result(stream, algo) ; + algo = algo->next ; + } +} + + +/* + * Prints an owl_result to the given stream. + */ +void owl_fprint_algorithm_result(FILE *stream, + owl_algorithm_result *algo) +{ + fprintf(stream, + "* Algorithm: %s\n" + " X: %f\n" + " Y: %f\n" + " Z: %f\n" + " Error: %f\n" + " Area: %s\n" + , + algo->algorithm, + algo->x, + algo->y, + algo->z, + algo->error, + algo->area ? algo->area : "" + ) ; +} + + + +/* + * Frees the memory allocated by an owl_result. + * Note that the pointer will not set to NULL. + */ +void owl_free_result(owl_result *result) +{ + if (! result) + return ; + while (result->results) + { + owl_algorithm_result *algo = result->results ; + result->results = algo->next ; + owl_free_algorithm_result(algo) ; + } + free(result->mobile_mac_addr) ; + free(result) ; +} + + +/* + * Frees the memory allocated by a single owl_algorithm_result (*not* + * recursively). + * Note that the pointer will not set to NULL. + */ +void owl_free_algorithm_result(owl_algorithm_result *algo) +{ + if (! algo) + return ; + free(algo->algorithm) ; + free(algo->area) ; + free(algo) ; +} diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.c b/libowlps-resultreader-udp/owlps-resultreader-udp.c new file mode 100644 index 0000000..5a3bef9 --- /dev/null +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.c @@ -0,0 +1,34 @@ +/* + * This is a simple program to demonstrate the use of + * libowlps-resultreader-udp. + * It must be linked against libowlps and its dependencies + * (see the Makefile). + */ + +#include "owlps-resultreader-udp.h" + +#include + +int main(void) +{ + owl_result *result ; + int sockfd ; + + sockfd = owl_create_udp_listening_socket(MOBILE_DEFAULT_PORT) ; + if (sockfd < 0) + return 1 ; + + while (1) + { + owl_receive_position(sockfd, &result) ; + if (result == NULL) + return 1 ; + owl_print_result(result) ; + owl_free_result(result) ; + printf("--------------\n") ; + } + + close(sockfd) ; + + return 0 ; +} diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h new file mode 100644 index 0000000..60d857a --- /dev/null +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -0,0 +1,70 @@ +/* + * This library provides functions to read results sent on UDP by OwlPS + * Positioning. + * See the example program owlps-resultreader-udp.c. + */ + +#ifndef _LIBOWLPS_RESULTREADER_CSV_ +#define _LIBOWLPS_RESULTREADER_CSV_ + +#include + +#include +#include + + +/* Maximum size of a result CSV string sent by OwlPS Positioning. + * Request's information: + * = 18 (MAC) + 2 (type) + 22 (timestamp) = 42 + * Plus, for each algorithm, about 60 characters (say 100, as the length + * of the algorithm and area names can vary). + * Let's keep room for 10 algorithms : + * 10×100 + 42 = 1042 characters + '\0' = 1043. + */ +#define OWL_CSV_RESULT_STRLEN 1043 + + +/* Linked list of algorithms' results. + * Each structure is the result of a single algorithm. + */ +typedef struct _owl_algorithm_result +{ + char *algorithm ; + float x ; + float y ; + float z ; + float error ; + char *area ; + + struct _owl_algorithm_result *next ; +} owl_algorithm_result ; + + +/* Results for a request. Includes the request's data, and the + * list of algorithms' results. + */ +typedef struct _owl_result +{ + char *mobile_mac_addr ; + uint8_t request_type ; + owl_timestamp mobile_timestamp ; + owl_algorithm_result *results ; +} owl_result ; + + +void owl_receive_position(int sockfd, owl_result **result) ; +void owl_fill_result(owl_result **result, char *csv) ; + +void owl_fprint_result(FILE *stream, owl_result *result) ; +void owl_fprint_algorithm_result(FILE *stream, + owl_algorithm_result *algo) ; +#define owl_print_result(RESULT) \ + (owl_fprint_result(stdout, (RESULT))) +#define owl_print_algorithm_result(ALGO) \ + (owl_fprint_algorithm_result(stdout, (ALGO))) + +void owl_free_result(owl_result *result) ; +void owl_free_algorithm_result(owl_algorithm_result *algo) ; + + +#endif // _LIBOWLPS_RESULTREADER_CSV_ diff --git a/libowlps/owlps.h b/libowlps/owlps.h index 7759248..feb3572 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -160,6 +160,10 @@ typedef struct _owl_autocalibration_order /* Misc. */ // Length of a MAC address in string format (including '\0') #define OWL_ETHER_ADDR_STRLEN 18 +// Maximum length of an algorithm name (including '\0') +#define OWL_ALGORITHM_STRLEN 31 +// Maximum length of an area name (including '\0') +#define OWL_AREA_STRLEN 31 /* Global variables */ From c7ba92cef963d3c443f09160fa8420192a47a302 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 19 Aug 2011 17:10:05 +0200 Subject: [PATCH 04/46] [lib-result] fprint_*(): const pointers & asserts owl_fprint_*(): - Mark pointer arguments as const. - Rename main argument "src". - Use assertion to check the source. --- .../libowlps-resultreader-udp.c | 32 +++++++++++-------- .../owlps-resultreader-udp.h | 12 +++---- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index bd09ba6..37cfd48 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -4,6 +4,8 @@ #include #include +#include + #define CSV_DELIMITER ";" @@ -183,23 +185,25 @@ void owl_fill_result(owl_result **result, char *csv) /* * Prints an owl_result to the given stream. */ -void owl_fprint_result(FILE *stream, owl_result *result) +void owl_fprint_result(FILE *stream, const owl_result *const src) { char timestamp_str[OWL_TIMESTAMP_STRLEN] ; - owl_timestamp_to_string(timestamp_str, result->mobile_timestamp) ; + assert(src) ; + + owl_timestamp_to_string(timestamp_str, src->mobile_timestamp) ; fprintf(stream, "Mobile MAC: %s\n" "Request type: %"PRIu8"\n" "Mobile timestamp: %s\n" "Results:\n" , - result->mobile_mac_addr, - result->request_type, + src->mobile_mac_addr, + src->request_type, timestamp_str ) ; - owl_algorithm_result *algo = result->results ; + owl_algorithm_result *algo = src->results ; while (algo) { owl_fprint_algorithm_result(stream, algo) ; @@ -209,11 +213,13 @@ void owl_fprint_result(FILE *stream, owl_result *result) /* - * Prints an owl_result to the given stream. + * Prints an owl_algorithm_result to the given stream. */ void owl_fprint_algorithm_result(FILE *stream, - owl_algorithm_result *algo) + const owl_algorithm_result *const src) { + assert(src) ; + fprintf(stream, "* Algorithm: %s\n" " X: %f\n" @@ -222,12 +228,12 @@ void owl_fprint_algorithm_result(FILE *stream, " Error: %f\n" " Area: %s\n" , - algo->algorithm, - algo->x, - algo->y, - algo->z, - algo->error, - algo->area ? algo->area : "" + src->algorithm, + src->x, + src->y, + src->z, + src->error, + src->area ? src->area : "" ) ; } diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index 60d857a..4ebc900 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -55,13 +55,13 @@ typedef struct _owl_result void owl_receive_position(int sockfd, owl_result **result) ; void owl_fill_result(owl_result **result, char *csv) ; -void owl_fprint_result(FILE *stream, owl_result *result) ; +void owl_fprint_result(FILE *stream, const owl_result *const src) ; void owl_fprint_algorithm_result(FILE *stream, - owl_algorithm_result *algo) ; -#define owl_print_result(RESULT) \ - (owl_fprint_result(stdout, (RESULT))) -#define owl_print_algorithm_result(ALGO) \ - (owl_fprint_algorithm_result(stdout, (ALGO))) + const owl_algorithm_result *const src) ; +#define owl_print_result(SRC) \ + (owl_fprint_result(stdout, (SRC))) +#define owl_print_algorithm_result(SRC) \ + (owl_fprint_algorithm_result(stdout, (SRC))) void owl_free_result(owl_result *result) ; void owl_free_algorithm_result(owl_algorithm_result *algo) ; From 44055929b18ee4ff31fc05530446020a91268ec6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 19 Aug 2011 17:14:20 +0200 Subject: [PATCH 05/46] [lib-result] Update OWL_CSV_RESULT_STRLEN Add OWL_CSV_RESULT_REQUEST_STRLEN & OWL_CSV_ALGORITHM_RESULT_STRLEN. --- libowlps-resultreader-udp/owlps-resultreader-udp.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index 4ebc900..9d72980 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -15,13 +15,15 @@ /* Maximum size of a result CSV string sent by OwlPS Positioning. * Request's information: - * = 18 (MAC) + 2 (type) + 22 (timestamp) = 42 + * = 18 (MAC) + 2 (type) + 22 (timestamp) = 42 + ';' = 43 * Plus, for each algorithm, about 60 characters (say 100, as the length - * of the algorithm and area names can vary). + * of the algorithm and area names can vary, 101 with the ';'). * Let's keep room for 10 algorithms : - * 10×100 + 42 = 1042 characters + '\0' = 1043. + * 10×101 + 43 = 1053 characters. */ -#define OWL_CSV_RESULT_STRLEN 1043 +#define OWL_CSV_RESULT_REQUEST_STRLEN 43 +#define OWL_CSV_ALGORITHM_RESULT_STRLEN 101 +#define OWL_CSV_RESULT_STRLEN 1053 /* Linked list of algorithms' results. From 8da063b597e6ce8515d76c842de684757a4f6547 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 19 Aug 2011 17:22:43 +0200 Subject: [PATCH 06/46] [lib-result] Add {algorithm,}result_to_csv() Add owl_result_to_csv() and owl_algorithm_result_to_csv(), that allow to get an owl_result or owl_algorithm_result as a CSV string. --- .../libowlps-resultreader-udp.c | 56 +++++++++++++++++++ .../owlps-resultreader-udp.h | 6 ++ 2 files changed, 62 insertions(+) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index 37cfd48..ee0da8f 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -182,6 +182,62 @@ void owl_fill_result(owl_result **result, char *csv) } +/* + * Converts an owl_result back to a CSV string. + * 'dst' must be an allocated string of at least OWL_CSV_RESULT_STRLEN + * characters. + */ +void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], + const owl_result *const src) +{ + size_t dst_len ; + char timestamp_str[OWL_TIMESTAMP_STRLEN] ; + + assert(src) ; + + owl_timestamp_to_string(timestamp_str, src->mobile_timestamp) ; + snprintf(dst, OWL_CSV_RESULT_REQUEST_STRLEN, + "%s;%"PRIu8";%s", + src->mobile_mac_addr, + src->request_type, + timestamp_str) ; + dst_len = strlen(dst) ; + + owl_algorithm_result *algo = src->results ; + while (algo) + { + char algo_str[OWL_CSV_ALGORITHM_RESULT_STRLEN] ; + owl_algorithm_result_to_csv(algo_str, algo) ; + dst[dst_len++] = ';' ; + strncpy(dst + dst_len, algo_str, OWL_CSV_ALGORITHM_RESULT_STRLEN) ; + dst_len += strlen(algo_str) ; + algo = algo->next ; + } +} + + +/* + * Converts an owl_algorithm_result back to a CSV string. + * 'dst' must be an allocated string of at least + * OWL_CSV_ALGORITHM_RESULT_STRLEN characters. + */ +void +owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], + const owl_algorithm_result *const src) +{ + assert(src) ; + + snprintf(dst, OWL_CSV_ALGORITHM_RESULT_STRLEN, + "%s;%f;%f;%f;%f;%s", + src->algorithm, + src->x, + src->y, + src->z, + src->error, + src->area ? src->area : "") ; +} + + /* * Prints an owl_result to the given stream. */ diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index 9d72980..ca5960a 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -57,6 +57,12 @@ typedef struct _owl_result void owl_receive_position(int sockfd, owl_result **result) ; void owl_fill_result(owl_result **result, char *csv) ; +void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], + const owl_result *const src) ; +void +owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], + const owl_algorithm_result *const src) ; + void owl_fprint_result(FILE *stream, const owl_result *const src) ; void owl_fprint_algorithm_result(FILE *stream, const owl_algorithm_result *const src) ; From a7ec7792317750074423b7bfe31a1677eac4fd24 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 08:57:29 +0200 Subject: [PATCH 07/46] [lib-result] owl_receive_position(): return a pointer Return a pointer instead of using a result argument. --- .../libowlps-resultreader-udp.c | 63 ++++++++++--------- .../owlps-resultreader-udp.c | 3 +- .../owlps-resultreader-udp.h | 4 +- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index ee0da8f..19e01d1 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -11,16 +11,14 @@ /* - * Receives a result from the socket of file descriptor 'sockfd' and - * fills an owl_result structure 'result'. + * Receives a result from the socket of file descriptor 'sockfd', fills + * an owl_result structure with the received information, and returns a + * pointer to it (or NULL in case of error). * - * Note that *result will be set by this function, and **result will - * point on a valid owl_result structure if everything goes well. - * You will have to free *result yourself with owl_free_result(). - * - * In case of error, *result is set to NULL. + * Note that the new owl_result is allocated with malloc() and must be + * deleted using free(). */ -void owl_receive_position(int sockfd, owl_result **result) +owl_result* owl_receive_position(int sockfd) { ssize_t nread ; // recvfrom return value char csv[OWL_CSV_RESULT_STRLEN] ; // Read string @@ -31,30 +29,35 @@ void owl_receive_position(int sockfd, owl_result **result) if (nread <= 0) { perror("No request received from listener") ; - *result = NULL ; - return ; + return NULL ; } - owl_fill_result(result, csv) ; + return owl_fill_result(csv) ; } -/* Splits the 'csv' string received from OwlPS Positioning and stores - * the fields in 'result' (which is allocated). +/* + * Splits the 'csv' string received from OwlPS Positioning and stores + * the fields in a new owl_result, and returns a pointer to it (or NULL + * in case of error). + * + * Note that the new owl_result is allocated with malloc() and must be + * deleted using free(). * * Handled CSV format: * Mobile_MAC;Request_type;Request_timestamp;Algorithm;X;Y;Z;Error;Area * The Request_timestamp format is: * seconds.nanoseconds */ -void owl_fill_result(owl_result **result, char *csv) +owl_result* owl_fill_result(char *csv) { char *csv_field = NULL ; + owl_result *result = NULL ; int nb_algorithms = 0 ; owl_algorithm_result *current_algo = NULL ; - *result = malloc(sizeof(owl_result)) ; - (*result)->results = NULL ; + result = malloc(sizeof(owl_result)) ; + memset(result, 0, sizeof(*result)) ; /* Mobile MAC address */ csv_field = strsep(&csv, CSV_DELIMITER) ; @@ -65,7 +68,7 @@ void owl_fill_result(owl_result **result, char *csv) " string (empty string?)!\n") ; goto error ; } - (*result)->mobile_mac_addr = + result->mobile_mac_addr = strndup(csv_field, OWL_ETHER_ADDR_STRLEN) ; /* Request type */ @@ -76,7 +79,7 @@ void owl_fill_result(owl_result **result, char *csv) "Error reading the request type from the CSV string!\n") ; goto error ; } - (*result)->request_type = atoi(csv_field) ; + result->request_type = atoi(csv_field) ; /* Timestamp */ // Seconds @@ -88,7 +91,7 @@ void owl_fill_result(owl_result **result, char *csv) " string!\n") ; goto error ; } - (*result)->mobile_timestamp.tv_sec = atol(csv_field) ; + result->mobile_timestamp.tv_sec = atol(csv_field) ; // Nanoseconds csv_field = strsep(&csv, CSV_DELIMITER) ; if (! csv_field) @@ -98,7 +101,7 @@ void owl_fill_result(owl_result **result, char *csv) " string!\n") ; goto error ; } - (*result)->mobile_timestamp.tv_nsec = atol(csv_field) ; + result->mobile_timestamp.tv_nsec = atol(csv_field) ; /* Algorithm results */ csv_field = strsep(&csv, CSV_DELIMITER) ; @@ -106,6 +109,7 @@ void owl_fill_result(owl_result **result, char *csv) { ++nb_algorithms ; current_algo = malloc(sizeof(owl_algorithm_result)) ; + memset(current_algo, 0, sizeof(*current_algo)) ; // Algorithm name if (! csv_field) @@ -168,17 +172,17 @@ void owl_fill_result(owl_result **result, char *csv) current_algo->area = strndup(csv_field, OWL_AREA_STRLEN) ; // Insert the current algorithm at the begining of the list - current_algo->next = (*result)->results ; - (*result)->results = current_algo ; + current_algo->next = result->results ; + result->results = current_algo ; } while ((csv_field = strsep(&csv, CSV_DELIMITER))) ; - return ; // Success + return result ; // Success error: - owl_free_result(*result) ; - *result = NULL ; - free(current_algo) ; + owl_free_result(result) ; + owl_free_algorithm_result(current_algo) ; + return NULL ; } @@ -296,7 +300,9 @@ void owl_fprint_algorithm_result(FILE *stream, /* - * Frees the memory allocated by an owl_result. + * Frees the memory allocated by an owl_result. The 'results' and + * 'mobile_mac_addr' fields *must* be defined, either to NULL or to a + * valid memory block allocated with malloc(). * Note that the pointer will not set to NULL. */ void owl_free_result(owl_result *result) @@ -316,7 +322,8 @@ void owl_free_result(owl_result *result) /* * Frees the memory allocated by a single owl_algorithm_result (*not* - * recursively). + * recursively). The 'algorithm' and 'area' fields *must* be defined, + * either to NULL or to a valid memory block allocated with malloc(). * Note that the pointer will not set to NULL. */ void owl_free_algorithm_result(owl_algorithm_result *algo) diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.c b/libowlps-resultreader-udp/owlps-resultreader-udp.c index 5a3bef9..a0cffc0 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.c @@ -20,8 +20,7 @@ int main(void) while (1) { - owl_receive_position(sockfd, &result) ; - if (result == NULL) + if (! (result = owl_receive_position(sockfd))) return 1 ; owl_print_result(result) ; owl_free_result(result) ; diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index ca5960a..f835cd1 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -54,8 +54,8 @@ typedef struct _owl_result } owl_result ; -void owl_receive_position(int sockfd, owl_result **result) ; -void owl_fill_result(owl_result **result, char *csv) ; +owl_result* owl_receive_position(int sockfd) ; +owl_result* owl_fill_result(char *csv) ; void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], const owl_result *const src) ; From 6fa903b14383090c3de1493aa308c4b74969ab50 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 10:03:50 +0200 Subject: [PATCH 08/46] [lib-result] Add owl_fill_algorithm_result() Create owl_fill_algorithm_result() from owl_fill_result(). --- .../libowlps-resultreader-udp.c | 159 ++++++++++-------- .../owlps-resultreader-udp.h | 1 + 2 files changed, 94 insertions(+), 66 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index 19e01d1..c384309 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -48,13 +48,13 @@ owl_result* owl_receive_position(int sockfd) * Mobile_MAC;Request_type;Request_timestamp;Algorithm;X;Y;Z;Error;Area * The Request_timestamp format is: * seconds.nanoseconds + * The Area field can be empty. */ owl_result* owl_fill_result(char *csv) { char *csv_field = NULL ; owl_result *result = NULL ; int nb_algorithms = 0 ; - owl_algorithm_result *current_algo = NULL ; result = malloc(sizeof(owl_result)) ; memset(result, 0, sizeof(*result)) ; @@ -104,84 +104,111 @@ owl_result* owl_fill_result(char *csv) result->mobile_timestamp.tv_nsec = atol(csv_field) ; /* Algorithm results */ - csv_field = strsep(&csv, CSV_DELIMITER) ; do { - ++nb_algorithms ; - current_algo = malloc(sizeof(owl_algorithm_result)) ; - memset(current_algo, 0, sizeof(*current_algo)) ; - - // Algorithm name - if (! csv_field) + owl_algorithm_result *current_algo = + owl_fill_algorithm_result(&csv) ; + if (current_algo == NULL) { - fprintf(stderr, - "Error reading the algorithm name from the CSV" - " string (algorithm #%d)!\n", nb_algorithms) ; - goto error ; + fprintf(stderr, "Error reading the algorithm #%d!\n", + nb_algorithms) ; + break ; } - current_algo->algorithm = - strndup(csv_field, OWL_ALGORITHM_STRLEN) ; - - // X coordinate - csv_field = strsep(&csv, CSV_DELIMITER) ; - if (! csv_field) - { - fprintf(stderr, - "Error reading the X coordinate from the CSV" - " string (algorithm #%d)!\n", nb_algorithms) ; - goto error ; - } - current_algo->x = atof(csv_field) ; - - // Y coordinate - csv_field = strsep(&csv, CSV_DELIMITER) ; - if (! csv_field) - { - fprintf(stderr, - "Error reading the Y coordinate from the CSV" - " string (algorithm #%d)!\n", nb_algorithms) ; - goto error ; - } - current_algo->y = atof(csv_field) ; - - // Z coordinate - csv_field = strsep(&csv, CSV_DELIMITER) ; - if (! csv_field) - { - fprintf(stderr, - "Error reading the Z coordinate from the CSV" - " string (algorithm #%d)!\n", nb_algorithms) ; - goto error ; - } - current_algo->z = atof(csv_field) ; - - // Distance error - csv_field = strsep(&csv, CSV_DELIMITER) ; - if (! csv_field) - { - fprintf(stderr, - "Error reading the distance error from the CSV" - " string (algorithm #%d)!\n", nb_algorithms) ; - goto error ; - } - current_algo->error = atof(csv_field) ; - - // Area name (optional) - csv_field = strsep(&csv, CSV_DELIMITER) ; - if (csv_field) - current_algo->area = strndup(csv_field, OWL_AREA_STRLEN) ; - // Insert the current algorithm at the begining of the list current_algo->next = result->results ; result->results = current_algo ; + ++nb_algorithms ; } - while ((csv_field = strsep(&csv, CSV_DELIMITER))) ; + while (csv) ; return result ; // Success error: owl_free_result(result) ; - owl_free_algorithm_result(current_algo) ; + return NULL ; +} + + +/* + * Splits the 'csv' string, stores the fields in a new + * owl_algorithm_result, and returns a pointer to it (or NULL + * in case of error). + * + * Note that the new owl_algorithm_result is allocated with malloc() + * and must be deleted using free(). + * + * 'csv' must follow this CSV format: + * Algorithm;X;Y;Z;Error;Area + * The Area field can be empty. + */ +owl_algorithm_result* owl_fill_algorithm_result(char **csv) +{ + owl_algorithm_result *algo ; + char *csv_field = NULL ; + + algo = malloc(sizeof(owl_algorithm_result)) ; + memset(algo, 0, sizeof(*algo)) ; + + // Algorithm name + csv_field = strsep(csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the algorithm name from the CSV string!\n") ; + goto error ; + } + algo->algorithm = + strndup(csv_field, OWL_ALGORITHM_STRLEN) ; + + // X coordinate + csv_field = strsep(csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the X coordinate from the CSV string!\n") ; + goto error ; + } + algo->x = atof(csv_field) ; + + // Y coordinate + csv_field = strsep(csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the Y coordinate from the CSV string!\n") ; + goto error ; + } + algo->y = atof(csv_field) ; + + // Z coordinate + csv_field = strsep(csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the Z coordinate from the CSV string!\n") ; + goto error ; + } + algo->z = atof(csv_field) ; + + // Distance error + csv_field = strsep(csv, CSV_DELIMITER) ; + if (! csv_field) + { + fprintf(stderr, + "Error reading the distance error from the CSV string!\n") ; + goto error ; + } + algo->error = atof(csv_field) ; + + // Area name (optional) + csv_field = strsep(csv, CSV_DELIMITER) ; + if (csv_field) + algo->area = strndup(csv_field, OWL_AREA_STRLEN) ; + + return algo ; // Success + + error: + owl_free_algorithm_result(algo) ; return NULL ; } diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index f835cd1..8e730e3 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -56,6 +56,7 @@ typedef struct _owl_result owl_result* owl_receive_position(int sockfd) ; owl_result* owl_fill_result(char *csv) ; +owl_algorithm_result* owl_fill_algorithm_result(char **csv) ; void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], const owl_result *const src) ; From 626242b5e2712deea57cf8210d5d6a61be12d0f4 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 11:10:12 +0200 Subject: [PATCH 09/46] [lib-result] example: handle signals Handle signals in the sample program owlps-resultreader-udp. --- .../owlps-resultreader-udp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.c b/libowlps-resultreader-udp/owlps-resultreader-udp.c index a0cffc0..69b6e25 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.c @@ -7,18 +7,31 @@ #include "owlps-resultreader-udp.h" +#include #include int main(void) { + struct sigaction action ; // Signal handler structure owl_result *result ; int sockfd ; + /* Set up signal handlers */ + action.sa_flags = 0 ; + sigemptyset(&action.sa_mask) ; + action.sa_handler = owl_sigint_handler ; + sigaction(SIGINT, &action, NULL) ; + action.sa_handler = owl_sigterm_handler ; + sigaction(SIGTERM, &action, NULL) ; + + /* Open the socket */ sockfd = owl_create_udp_listening_socket(MOBILE_DEFAULT_PORT) ; if (sockfd < 0) return 1 ; - while (1) + /* Read loop */ + owl_run = TRUE ; + while (owl_run) { if (! (result = owl_receive_position(sockfd))) return 1 ; @@ -27,6 +40,7 @@ int main(void) printf("--------------\n") ; } + /* Cleaning */ close(sockfd) ; return 0 ; From 462298d6e85505ea403ebfdd2a8785365eae7fc6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 18:17:57 +0200 Subject: [PATCH 10/46] [Listener] Set the signal flags to 0 --- owlps-listener/owlps-listenerd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 4e0e8d9..fd1c547 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -125,6 +125,7 @@ int main(int argc, char *argv[]) owl_run = TRUE ; /* Set up signal handlers */ + action.sa_flags = 0 ; sigemptyset(&action.sa_mask) ; action.sa_handler = sigint_handler ; sigaction(SIGINT, &action, NULL) ; From 8327357290f3b6b95cc1bb0de099742971db23db Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 18:25:28 +0200 Subject: [PATCH 11/46] Makefiles: allow to enable -g easily Add a commented line DEBUG=-g in each Makefile. --- libowlps-client/Makefile | 1 + libowlps-client/Makefile_atheros_openwrt-10.03 | 1 + libowlps-client/Makefile_atheros_openwrt-8.09 | 1 + libowlps-resultreader-udp/Makefile | 1 + libowlps/Makefile | 1 + libowlps/Makefile_atheros_openwrt-10.03 | 1 + libowlps/Makefile_atheros_openwrt-8.09 | 1 + owlps-aggregator/Makefile | 1 + owlps-client/Makefile | 2 ++ owlps-client/Makefile_atheros_openwrt-10.03 | 1 + owlps-client/Makefile_atheros_openwrt-8.09 | 1 + owlps-listener/Makefile | 1 + owlps-listener/Makefile_atheros_openwrt-10.03 | 1 + owlps-listener/Makefile_atheros_openwrt-8.09 | 1 + owlps-positioning/Makefile | 4 ++-- 15 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libowlps-client/Makefile b/libowlps-client/Makefile index 033d797..04556b6 100644 --- a/libowlps-client/Makefile +++ b/libowlps-client/Makefile @@ -23,6 +23,7 @@ OBJS=$(LIB_CIBLE).o # Flags LIBOWLPS_DIR = ../libowlps CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +#CFLAGS += -g -O0 CFLAGS += -D DEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps-client/Makefile_atheros_openwrt-10.03 b/libowlps-client/Makefile_atheros_openwrt-10.03 index 5cb21ed..b874e5c 100644 --- a/libowlps-client/Makefile_atheros_openwrt-10.03 +++ b/libowlps-client/Makefile_atheros_openwrt-10.03 @@ -26,6 +26,7 @@ OBJS=$(LIB_CIBLE).o # Flags LIBOWLPS_DIR = ../libowlps CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +#CFLAGS += -g -O0 CFLAGS += -D DEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps-client/Makefile_atheros_openwrt-8.09 b/libowlps-client/Makefile_atheros_openwrt-8.09 index 95b4248..0e1e12b 100644 --- a/libowlps-client/Makefile_atheros_openwrt-8.09 +++ b/libowlps-client/Makefile_atheros_openwrt-8.09 @@ -26,6 +26,7 @@ OBJS=$(LIB_CIBLE).o # Flags LIBOWLPS_DIR = ../libowlps CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +#CFLAGS += -g -O0 CFLAGS += -D DEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps-resultreader-udp/Makefile b/libowlps-resultreader-udp/Makefile index 21213a4..10b8b9d 100644 --- a/libowlps-resultreader-udp/Makefile +++ b/libowlps-resultreader-udp/Makefile @@ -24,6 +24,7 @@ OBJS = $(LIB_CIBLE).o # Flags LIBOWLPS_DIR = ../libowlps CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +#CFLAGS += -g -O0 CFLAGS += -D DEBUG DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps/Makefile b/libowlps/Makefile index 0afa9f3..5a3374d 100644 --- a/libowlps/Makefile +++ b/libowlps/Makefile @@ -35,6 +35,7 @@ OBJS=$(LIB_CIBLE).o # Flags CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O +#CFLAGS += -g -O0 #CFLAGS += -D NDEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps/Makefile_atheros_openwrt-10.03 b/libowlps/Makefile_atheros_openwrt-10.03 index e9f76cd..197c8c5 100644 --- a/libowlps/Makefile_atheros_openwrt-10.03 +++ b/libowlps/Makefile_atheros_openwrt-10.03 @@ -38,6 +38,7 @@ OBJS=$(LIB_CIBLE).o # Flags CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O +#CFLAGS += -g -O0 #CFLAGS += -D NDEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/libowlps/Makefile_atheros_openwrt-8.09 b/libowlps/Makefile_atheros_openwrt-8.09 index 2543c40..dbbfba1 100644 --- a/libowlps/Makefile_atheros_openwrt-8.09 +++ b/libowlps/Makefile_atheros_openwrt-8.09 @@ -38,6 +38,7 @@ OBJS=$(LIB_CIBLE).o # Flags CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O +#CFLAGS += -g -O0 #CFLAGS += -D NDEBUG DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) diff --git a/owlps-aggregator/Makefile b/owlps-aggregator/Makefile index 8767453..f1ef561 100644 --- a/owlps-aggregator/Makefile +++ b/owlps-aggregator/Makefile @@ -27,6 +27,7 @@ HEADER=owlps-aggregator.h # Flags LIBOWLPS_DIR = ../libowlps CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -O -I$(LIBOWLPS_DIR) +#CFLAGS += -g -O0 DEPFLAGS=-MMD XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG=-fPIC diff --git a/owlps-client/Makefile b/owlps-client/Makefile index 68fabe0..a81b1da 100644 --- a/owlps-client/Makefile +++ b/owlps-client/Makefile @@ -29,6 +29,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC @@ -93,6 +94,7 @@ purge : clean help : @echo "Bibliothèques nécessaires à la compilation :" @echo " libowlps1.0 (fournie)" + @echo " libowlps-client1.0 (fournie)" @echo @echo "Cibles possibles :" @echo " $(TARGET) (cible par défaut) : Compile le programme \ diff --git a/owlps-client/Makefile_atheros_openwrt-10.03 b/owlps-client/Makefile_atheros_openwrt-10.03 index b7c93b1..516ea76 100644 --- a/owlps-client/Makefile_atheros_openwrt-10.03 +++ b/owlps-client/Makefile_atheros_openwrt-10.03 @@ -32,6 +32,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC diff --git a/owlps-client/Makefile_atheros_openwrt-8.09 b/owlps-client/Makefile_atheros_openwrt-8.09 index 702da67..15ab520 100644 --- a/owlps-client/Makefile_atheros_openwrt-8.09 +++ b/owlps-client/Makefile_atheros_openwrt-8.09 @@ -32,6 +32,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC diff --git a/owlps-listener/Makefile b/owlps-listener/Makefile index fb08469..58141d9 100644 --- a/owlps-listener/Makefile +++ b/owlps-listener/Makefile @@ -29,6 +29,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC diff --git a/owlps-listener/Makefile_atheros_openwrt-10.03 b/owlps-listener/Makefile_atheros_openwrt-10.03 index 343175e..7799960 100644 --- a/owlps-listener/Makefile_atheros_openwrt-10.03 +++ b/owlps-listener/Makefile_atheros_openwrt-10.03 @@ -32,6 +32,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC diff --git a/owlps-listener/Makefile_atheros_openwrt-8.09 b/owlps-listener/Makefile_atheros_openwrt-8.09 index a5bc864..2151bf9 100644 --- a/owlps-listener/Makefile_atheros_openwrt-8.09 +++ b/owlps-listener/Makefile_atheros_openwrt-8.09 @@ -32,6 +32,7 @@ LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) +#CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index ab42305..0bb79e7 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -33,9 +33,9 @@ endif # Flags LIBOWLPS_DIR = ../libowlps -#DEBUG = -g TESTSGXXFLAGS = -I$(TESTS_DIR) -I$(SRC_DIR) -I. -GXXFLAGS = $(DEBUG) -O2 -Wall -Wextra -I$(LIBOWLPS_DIR) +GXXFLAGS = -O2 -Wall -Wextra -I$(LIBOWLPS_DIR) +#GXXFLAGS += -g -O0 LD = $(CXX) LDFLAGS = -lstdc++ -lm -lboost_program_options \ -L$(LIBOWLPS_DIR) -lowlps From b68cb179a9b3e10e5f683d477e0e232e70bf6de2 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 18:33:47 +0200 Subject: [PATCH 12/46] [Client] Handle signals --- TODO | 1 - owlps-client/owlps-client.c | 13 ++++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 5279ed0..7fd9f0a 100644 --- a/TODO +++ b/TODO @@ -59,7 +59,6 @@ * Client -- Handle signals. - Add verbose & quiet options. - Log sent requests? - Allow to use a string for the direction? diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 95ca65d..33c616f 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -88,9 +89,19 @@ uint_fast16_t packet_size ; // Packet size int main(int argc, char *argv[]) { + struct sigaction action ; // Signal handler structure + program_name = argv[0] ; parse_command_line(argc, argv) ; + /* Set up signal handlers */ + action.sa_flags = 0 ; + sigemptyset(&action.sa_mask) ; + action.sa_handler = owl_sigint_handler ; + sigaction(SIGINT, &action, NULL) ; + action.sa_handler = owl_sigterm_handler ; + sigaction(SIGTERM, &action, NULL) ; + create_socket() ; request_transmission: @@ -98,7 +109,7 @@ int main(int argc, char *argv[]) send_request() ; free(packet) ; - if (options.flood_delay >= 0) + if (options.flood_delay >= 0 && owl_run) { usleep(options.flood_delay * 1000) ; goto request_transmission ; From d566187f429616fe401eeb539db01a8aa3507186 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 18:45:23 +0200 Subject: [PATCH 13/46] [Client] Fix "blinking" coordinates in flood mode In calibration flood mode, the coordinates were "blinking" (correct values, then 0, etc.). This is now fixed. --- owlps-client/owlps-client.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 33c616f..4d465a3 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -410,14 +410,21 @@ void make_packet() printf("Direction = %d, X = %f, Y = %f, Z = %f\n", packet[offset - 1], options.x, options.y, options.z) ; #endif // DEBUG + // Convert the coordinates to the network endianess options.x = owl_htonf(options.x) ; options.y = owl_htonf(options.y) ; options.z = owl_htonf(options.z) ; + // Copy the coordinates to the packet memcpy(&packet[offset], &options.x, sizeof(float)) ; offset += sizeof(float) ; memcpy(&packet[offset], &options.y, sizeof(float)) ; offset += sizeof(float) ; memcpy(&packet[offset], &options.z, sizeof(float)) ; + // Convert the coordinates back to the host endianess (mandatory + // in flood mode) + options.x = owl_ntohf(options.x) ; + options.y = owl_ntohf(options.y) ; + options.z = owl_ntohf(options.z) ; } else // Standard packet From 1d6016a3ce3ad554200995a01af41d9d08b5f479 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 18:56:55 +0200 Subject: [PATCH 14/46] [lib] Move listener code to owlps-listener.h (bis) Move the last piece of listener-specific code from owlps.h to owlps-listener.h. --- libowlps/owlps.h | 10 ---------- owlps-listener/owlps-listener.h | 7 +++++++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/libowlps/owlps.h b/libowlps/owlps.h index feb3572..e024cf3 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -230,16 +230,6 @@ void owl_close_fd(void *const fd) ; void owl_close_file(void *const file) ; -/* Macros */ - -/* - * Test if a IEEE 802.11 frame is a retry. - * Input: IEEE 802.11 header flags. - * Returns 0 if the Retry bit is absent, a positive value if present. - */ -#define IS_RETRY(IEEE80211_FLAGS) ((IEEE80211_FLAGS) & 0x08) - - #ifdef __cplusplus } #endif // __cplusplus diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index fd657e8..f7e624b 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -94,6 +94,13 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ; #define IS_FRAME_FROM_STA(FC2) \ (((FC2) & FRAME_FROM_STA_MASK) != FRAME_FROM_STA_MASK) +/* + * Test if a IEEE 802.11 frame is a retry. + * Input: IEEE 802.11 header flags. + * Returns 0 if the Retry bit is absent, a positive value if present. + */ +#define IS_RETRY(IEEE80211_FLAGS) ((IEEE80211_FLAGS) & 0x08) + /* Positions of the radiotap header fixed fields (in bytes) */ #define RTAP_P_HREVISION 0 // Header revision From 442c5a4601f3cce54254b6e37c526dfaa23f54ed Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 19:28:31 +0200 Subject: [PATCH 15/46] [lib] .h all is prefixed with OWL_ or owl_ All the types, defines, etc. are now prefixed with "OWL_" or "owl_". TRUE and FALSE become owl_true and owl_false. --- .../owlps-resultreader-udp.c | 4 +- libowlps/libowlps.c | 14 +-- libowlps/owlps.h | 18 ++-- owlps-aggregator/owlps-aggregatord.c | 18 ++-- owlps-client/owlps-client.c | 18 ++-- owlps-listener/owlps-listener.h | 8 +- owlps-listener/owlps-listenerd.c | 89 ++++++++++--------- owlps-positioning/src/owlps-positioning.cc | 2 +- owlps-positioning/src/userinterface.cc | 4 +- 9 files changed, 88 insertions(+), 87 deletions(-) diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.c b/libowlps-resultreader-udp/owlps-resultreader-udp.c index 69b6e25..e8bfbb2 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.c @@ -25,12 +25,12 @@ int main(void) sigaction(SIGTERM, &action, NULL) ; /* Open the socket */ - sockfd = owl_create_udp_listening_socket(MOBILE_DEFAULT_PORT) ; + sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; if (sockfd < 0) return 1 ; /* Read loop */ - owl_run = TRUE ; + owl_run = owl_true ; while (owl_run) { if (! (result = owl_receive_position(sockfd))) diff --git a/libowlps/libowlps.c b/libowlps/libowlps.c index 9b0e1b8..b75f005 100644 --- a/libowlps/libowlps.c +++ b/libowlps/libowlps.c @@ -19,7 +19,7 @@ -owl_bool owl_run = TRUE ; +owl_bool owl_run = owl_true ; @@ -57,7 +57,7 @@ void owl_mac_bytes_to_string_r(const uint8_t *const mac_binary, /* * Compares two MAC addresses. - * Returns TRUE if they are identical, FALSE otherwise. + * Returns owl_true if they are identical, owl_false otherwise. */ owl_bool owl_mac_equals(const uint8_t *const mac1, const uint8_t *const mac2) @@ -65,8 +65,8 @@ owl_bool owl_mac_equals(const uint8_t *const mac1, int i ; for (i = 0 ; i < ETHER_ADDR_LEN ; ++i) if(mac1[i] != mac2[i]) - return FALSE ; - return TRUE ; + return owl_false ; + return owl_true ; } @@ -383,10 +383,10 @@ void owl_sigint_handler(const int num) { fprintf(stderr, "Error! The SIGINT handler was called but the" " signal is not SIGINT.\n") ; - exit(ERR_BAD_SIGNAL) ; + exit(OWL_ERR_BAD_SIGNAL) ; } - owl_run = FALSE ; + owl_run = owl_false ; #ifndef NDEBUG fprintf(stderr, "\nSignal received: end.\n"); @@ -404,7 +404,7 @@ void owl_sigterm_handler(const int num) { fprintf(stderr, "Error! The SIGTERM handler was called but the" " signal is not SIGTERM.\n") ; - exit(ERR_BAD_SIGNAL) ; + exit(OWL_ERR_BAD_SIGNAL) ; } owl_sigint_handler(SIGINT) ; diff --git a/libowlps/owlps.h b/libowlps/owlps.h index e024cf3..5eb6526 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -20,27 +20,27 @@ extern "C" { // Port on which the positioning request is sent by the mobile: -#define LOC_REQUEST_DEFAULT_PORT 9900 +#define OWL_DEFAULT_REQUEST_PORT 9900 // Port on which listeners and aggregator communicate: -#define AGGREGATE_DEFAULT_PORT 9901 +#define OWL_DEFAULT_LISTENER_PORT 9901 // Port on which aggregator and positioning server communicate: -#define POSITIONER_DEFAULT_PORT 9902 +#define OWL_DEFAULT_AGGREGATION_PORT 9902 // Port on which autocalibration requests are sent by the listeners: -#define DEFAULT_AUTOCALIBRATION_REQUEST_PORT 9903 +#define OWL_DEFAULT_AUTOCALIBRATION_REQUEST_PORT 9903 // Port on which the aggregator listens for hello messages from the // listeners, and the listeners listen for orders from the aggregator: -#define DEFAULT_AUTOCALIBRATION_PORT 9904 +#define OWL_DEFAULT_AUTOCALIBRATION_PORT 9904 // Port on which the mobile listens for its position: -#define MOBILE_DEFAULT_PORT 9910 +#define OWL_DEFAULT_RESULT_PORT 9910 /* Boolean type */ -typedef enum {FALSE, TRUE} owl_bool ; +typedef enum {owl_false, owl_true} owl_bool ; #define OWL_BOOL_TO_STRING(B) ((B) ? "true" : "false") /* Direction type */ -enum {NORTH = 1, EAST, SOUTH, WEST} ; +enum {owl_north = 1, owl_east, owl_south, owl_west} ; #define OWL_DIRECTION_MIN 1 #define OWL_DIRECTION_MAX 4 typedef uint8_t owl_direction ; @@ -172,7 +172,7 @@ extern owl_bool owl_run ; /* Function error codes */ -#define ERR_BAD_SIGNAL 111 +#define OWL_ERR_BAD_SIGNAL 111 /* Function headers */ diff --git a/owlps-aggregator/owlps-aggregatord.c b/owlps-aggregator/owlps-aggregatord.c index efa9be5..d357514 100644 --- a/owlps-aggregator/owlps-aggregatord.c +++ b/owlps-aggregator/owlps-aggregatord.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) } } - owl_run = TRUE ; + owl_run = owl_true ; ret = read_loop(sockfd) ; /* Wait for the threads to terminate */ @@ -178,10 +178,10 @@ void parse_config_file(int argc, char **argv) CFG_INT("verbose", 0, CFGF_NONE), // Aggregation listening port - CFG_INT("listening_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), + CFG_INT("listening_port", OWL_DEFAULT_LISTENER_PORT, CFGF_NONE), // Port and IP address of the localisation server: - CFG_INT("positioner_port", POSITIONER_DEFAULT_PORT, CFGF_NONE), + CFG_INT("positioner_port", OWL_DEFAULT_AGGREGATION_PORT, CFGF_NONE), CFG_STR("positioner_ip", POSITIONER_DEFAULT_IP, CFGF_NONE), CFG_STR("output_file", "", CFGF_NONE), @@ -196,7 +196,7 @@ void parse_config_file(int argc, char **argv) // Autocalibration activated? CFG_BOOL("autocalibration", cfg_false, CFGF_NONE), // Port on which autocalibration data are exchanged: - CFG_INT("autocalibration_port", DEFAULT_AUTOCALIBRATION_PORT, + CFG_INT("autocalibration_port", OWL_DEFAULT_AUTOCALIBRATION_PORT, CFGF_NONE), // Time we keep APs in the list (in seconds): CFG_INT("ap_keep_timeout", DEFAULT_AP_KEEP_TIMEOUT, CFGF_NONE), @@ -339,7 +339,7 @@ void check_configuration() if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad listening_port:" " failing back to the default value.\n") ; - cfg_setint(cfg, "listening_port", AGGREGATE_DEFAULT_PORT) ; + cfg_setint(cfg, "listening_port", OWL_DEFAULT_LISTENER_PORT) ; } // positioner_port // @@ -349,7 +349,7 @@ void check_configuration() if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad positioner_port:" " failing back to the default value.\n") ; - cfg_setint(cfg, "positioner_port", POSITIONER_DEFAULT_PORT) ; + cfg_setint(cfg, "positioner_port", OWL_DEFAULT_AGGREGATION_PORT) ; } // positioner_ip // @@ -1329,12 +1329,12 @@ void print_usage() program_name, DEFAULT_CONFIG_FILE, POSITIONER_DEFAULT_IP, - POSITIONER_DEFAULT_PORT, - AGGREGATE_DEFAULT_PORT, + OWL_DEFAULT_AGGREGATION_PORT, + OWL_DEFAULT_LISTENER_PORT, DEFAULT_AGGREGATE_TIMEOUT, DEFAULT_KEEP_TIMEOUT, DEFAULT_CHECK_INTERVAL, - DEFAULT_AUTOCALIBRATION_PORT, + OWL_DEFAULT_AUTOCALIBRATION_PORT, DEFAULT_AP_KEEP_TIMEOUT, DEFAULT_AP_CHECK_INTERVAL ) ; diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 4d465a3..c630c3f 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -65,7 +65,7 @@ struct { float z ; } options = { "", - LOC_REQUEST_DEFAULT_PORT, + OWL_DEFAULT_REQUEST_PORT, "", -1, 0, @@ -76,9 +76,9 @@ struct { char *program_name = NULL ; -// TRUE if the packet is a calibration request, FALSE if it is a simple -// positioning request: -owl_bool is_calibration_request = FALSE ; +// owl_true if the packet is a calibration request, owl_false if it is +// a simple positioning request: +owl_bool is_calibration_request = owl_false ; int sockfd ; // Sending socket descriptor struct sockaddr_in server ; // Server info @@ -190,7 +190,7 @@ void parse_main_options(int argc, char **argv) * is an option, we have -l without a port number */ if (argv[optind] == NULL || argv[optind][0] == '-') // Take the default value: - options.listening_port = MOBILE_DEFAULT_PORT ; + options.listening_port = OWL_DEFAULT_RESULT_PORT ; else { // Take the optind value: @@ -242,7 +242,7 @@ void parse_calibration_data(int argc, char **argv) { if (argc - optind == 4) { - is_calibration_request = TRUE ; + is_calibration_request = owl_true ; options.direction = strtoul(argv[optind++], NULL, 0) ; options.x = strtod(argv[optind++], NULL) ; options.y = strtod(argv[optind++], NULL) ; @@ -302,7 +302,7 @@ void check_configuration() #ifdef DEBUG fprintf(stderr, "Warning! Bad dest_port:" " failing back to default value.\n") ; - options.dest_port = LOC_REQUEST_DEFAULT_PORT ; + options.dest_port = OWL_DEFAULT_REQUEST_PORT ; #endif // DEBUG } if (options.listening_port > 65535) @@ -500,13 +500,13 @@ void print_usage() , program_name, program_name, - LOC_REQUEST_DEFAULT_PORT, + OWL_DEFAULT_REQUEST_PORT, DEFAULT_DELAY_NORMAL, DEFAULT_DELAY_CALIB, DEFAULT_NBPKT_NORMAL, DEFAULT_NBPKT_CALIB, DEFAULT_FLOOD_DELAY, - MOBILE_DEFAULT_PORT + OWL_DEFAULT_RESULT_PORT ) ; } diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index f7e624b..7d5198d 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -314,7 +314,7 @@ void print_version(void) ; (options.aggregation_ip) #ifdef USE_PTHREAD #define SET_KEEP_MONITOR() \ - (options.keep_monitor = TRUE) + (options.keep_monitor = owl_true) #define GET_KEEP_MONITOR() \ (options.keep_monitor) #endif // USE_PTHREAD @@ -337,7 +337,7 @@ void print_version(void) ; #ifdef USE_PTHREAD #define SET_AUTOCALIBRATION() \ - (options.autocalibration = TRUE) + (options.autocalibration = owl_true) #define GET_AUTOCALIBRATION() \ (options.autocalibration) #define SET_AUTOCALIBRATION_IP(IP) \ @@ -389,9 +389,9 @@ void print_version(void) ; #define GET_VERBOSE() \ (options.verbose) #define SET_DISPLAY_CAPTURED() \ - (options.display_captured = TRUE) + (options.display_captured = owl_true) #define UNSET_DISPLAY_CAPTURED() \ - (options.display_captured = FALSE) + (options.display_captured = owl_false) #define GET_DISPLAY_CAPTURED() \ (options.display_captured) #endif // USE_CONFIG_FILE diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index fd1c547..739cdc1 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -45,8 +45,8 @@ 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 ; +// owl_true if the coordinates of the listener were provided by the user: +owl_bool coordinates_provided = owl_false ; #endif // USE_PTHREAD #ifdef USE_CONFIG_FILE @@ -84,25 +84,25 @@ struct { } options = { // Initalise default options: MODE_ACTIVE, "127.0.0.1", - AGGREGATE_DEFAULT_PORT, - LOC_REQUEST_DEFAULT_PORT, + OWL_DEFAULT_LISTENER_PORT, + OWL_DEFAULT_REQUEST_PORT, #ifdef USE_PTHREAD - FALSE, + owl_false, #endif // USE_PTHREAD "", "", #ifdef USE_PTHREAD - FALSE, + owl_false, "", - DEFAULT_AUTOCALIBRATION_REQUEST_PORT, - DEFAULT_AUTOCALIBRATION_PORT, + OWL_DEFAULT_AUTOCALIBRATION_REQUEST_PORT, + OWL_DEFAULT_AUTOCALIBRATION_PORT, DEFAULT_AUTOCALIBRATION_HELLO_DELAY, DEFAULT_AUTOCALIBRATION_DELAY, DEFAULT_AUTOCALIBRATION_NBPKT, 0, 0, 0, 0, #endif // USE_PTHREAD 0, - FALSE + owl_false } ; #endif // USE_CONFIG_FILE @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) program_name = argv[0] ; initialise_configuration(argc, argv) ; - owl_run = TRUE ; + owl_run = owl_true ; /* Set up signal handlers */ action.sa_flags = 0 ; @@ -269,9 +269,9 @@ void parse_config_file(int argc, char **argv) // IP address of the aggregator (default: loopback): CFG_STR("aggregation_ip", "127.0.0.1", CFGF_NONE), // Port on which the aggregator listens: - CFG_INT("aggregation_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), + CFG_INT("aggregation_port", OWL_DEFAULT_LISTENER_PORT, CFGF_NONE), // Port on which mobiles send active requests: - CFG_INT("listening_port", LOC_REQUEST_DEFAULT_PORT, CFGF_NONE), + CFG_INT("listening_port", OWL_DEFAULT_REQUEST_PORT, CFGF_NONE), #ifdef USE_PTHREAD // Activate the active monitor mode keeping-up (read the code if // you do not understand what I mean): @@ -290,9 +290,9 @@ void parse_config_file(int argc, char **argv) CFG_STR("autocalibration_ip", "", CFGF_NONE), // Port on which autocalibration requests are sent: CFG_INT("autocalibration_request_port", - DEFAULT_AUTOCALIBRATION_REQUEST_PORT, CFGF_NONE), + OWL_DEFAULT_AUTOCALIBRATION_REQUEST_PORT, CFGF_NONE), // Port on which autocalibration data are exchanged: - CFG_INT("autocalibration_port", DEFAULT_AUTOCALIBRATION_PORT, + CFG_INT("autocalibration_port", OWL_DEFAULT_AUTOCALIBRATION_PORT, CFGF_NONE), // Delay between two hello messages: CFG_INT("autocalibration_hello_delay", @@ -505,7 +505,7 @@ void parse_calibration_data(int argc, char **argv) { if (argc - optind == 4) { - coordinates_provided = TRUE ; + coordinates_provided = owl_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)) ; @@ -559,14 +559,14 @@ void check_configuration() if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad aggregation_port:" " failing back to the default value.\n") ; - SET_AGGREGATION_PORT(AGGREGATE_DEFAULT_PORT) ; + SET_AGGREGATION_PORT(OWL_DEFAULT_LISTENER_PORT) ; } if (GET_LISTENING_PORT() < 1 || GET_LISTENING_PORT() > 65535) { if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad listening_port:" " failing back to the default value.\n") ; - SET_LISTENING_PORT(LOC_REQUEST_DEFAULT_PORT) ; + SET_LISTENING_PORT(OWL_DEFAULT_REQUEST_PORT) ; } // Autocalibration stuff // @@ -599,7 +599,7 @@ void check_configuration() if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad autocalibration_request_port:" " failing back to the default value.\n") ; - SET_AUTOCALIBRATION_REQUEST_PORT(DEFAULT_AUTOCALIBRATION_REQUEST_PORT) ; + SET_AUTOCALIBRATION_REQUEST_PORT(OWL_DEFAULT_AUTOCALIBRATION_REQUEST_PORT) ; } if (GET_AUTOCALIBRATION_PORT() < 1 || GET_AUTOCALIBRATION_PORT() > 65535) @@ -607,7 +607,7 @@ void check_configuration() if (VERBOSE_WARNING) fprintf(stderr, "Warning! Bad autocalibration_port:" " failing back to the default value.\n") ; - SET_AUTOCALIBRATION_PORT(DEFAULT_AUTOCALIBRATION_PORT) ; + SET_AUTOCALIBRATION_PORT(OWL_DEFAULT_AUTOCALIBRATION_PORT) ; } } #endif // USE_PTHREAD @@ -785,9 +785,10 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Pointer to the (possible) UDP header of the packet: struct udphdr *packet_udp_header = NULL ; // Localisation request type (request, calibration, autocalibration): - owl_bool is_explicit_packet = TRUE ; // Is the packet an explicit request? + // Is the packet an explicit request? + owl_bool is_explicit_packet = owl_true ; // Is the packet an autocalibration positioning request? - owl_bool uses_autocalibration_request_port = FALSE ; + owl_bool uses_autocalibration_request_port = owl_false ; ssize_t nsent ; // sendto return value // Blank the request: @@ -853,7 +854,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, #ifdef USE_PTHREAD if (GET_AUTOCALIBRATION() && dest_port == (uint_fast16_t) GET_AUTOCALIBRATION_REQUEST_PORT()) - uses_autocalibration_request_port = TRUE ; + uses_autocalibration_request_port = owl_true ; else #endif // USE_PTHREAD if (dest_port != (uint_fast16_t) GET_LISTENING_PORT()) @@ -865,7 +866,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, not_explicit_packet : if (GET_MODE() == MODE_ACTIVE) return ; - is_explicit_packet = FALSE ; + is_explicit_packet = owl_false ; process_packet : @@ -936,7 +937,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, printf("\nStrange explicit packet received\n") ; fprintf(stderr, "Error! Unknown request type (%d).\n", request.type) ; - is_explicit_packet = FALSE ; + is_explicit_packet = owl_false ; } if (! is_explicit_packet) @@ -1042,7 +1043,7 @@ void extract_calibration_data(const u_char *packet, /* * Fills 'request' with the required data extracted from the Radiotap - * header of 'packet'. The elements of 'rtap_fields' are set to TRUE + * header of 'packet'. The elements of 'rtap_fields' are set to owl_true * when the corresponding Radiotap flag is found in the packet. */ void extract_radiotap_data(const u_char *packet, @@ -1060,7 +1061,7 @@ void extract_radiotap_data(const u_char *packet, rtap_presentflags = le32toh(rtap_presentflags) ; for (i = 0 ; i < 15 ; ++i) // Initialise present flags structure - rtap_fields[i] = FALSE ; + rtap_fields[i] = owl_false ; rtap_position = 8 ; // Begining of the present flags determined fields // Test the first 15 bits of the flag field in order to check their @@ -1072,15 +1073,15 @@ void extract_radiotap_data(const u_char *packet, switch(i) { case RTAP_MACTS: - rtap_fields[RTAP_MACTS] = TRUE ; + rtap_fields[RTAP_MACTS] = owl_true ; rtap_position += RTAP_L_MACTS ; break ; case RTAP_FLAGS: - rtap_fields[RTAP_FLAGS] = TRUE; + rtap_fields[RTAP_FLAGS] = owl_true; rtap_position += RTAP_L_FLAGS ; break ; case RTAP_RATE: - rtap_fields[RTAP_RATE] = TRUE; + rtap_fields[RTAP_RATE] = owl_true; rtap_position += RTAP_L_RATE ; break ; case RTAP_CHANNEL: @@ -1088,52 +1089,52 @@ void extract_radiotap_data(const u_char *packet, rtap_position += RTAP_L_CHANNELTYPE ; break ; case RTAP_FHSS: - rtap_fields[RTAP_FHSS] = TRUE; + rtap_fields[RTAP_FHSS] = owl_true; rtap_position += RTAP_L_FHSS ; break ; case RTAP_ANTENNASIGNALDBM: memcpy(&request->antenna_signal_dbm, &packet[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; - rtap_fields[RTAP_ANTENNASIGNALDBM] = TRUE; + rtap_fields[RTAP_ANTENNASIGNALDBM] = owl_true; if (VERBOSE_INFO) printf("Antenna signal: %d dBm\n", request->antenna_signal_dbm - 0x100); rtap_position += RTAP_L_ANTENNASIGNALDBM ; break ; case RTAP_ANTENNANOISEDBM: - rtap_fields[RTAP_ANTENNANOISEDBM] = TRUE; + rtap_fields[RTAP_ANTENNANOISEDBM] = owl_true; rtap_position += RTAP_L_ANTENNANOISEDBM ; break ; case RTAP_LOCKQUALITY: - rtap_fields[RTAP_LOCKQUALITY] = TRUE; + rtap_fields[RTAP_LOCKQUALITY] = owl_true; rtap_position += RTAP_L_LOCKQUALITY ; break ; case RTAP_TXATTENUATION: - rtap_fields[RTAP_TXATTENUATION] = TRUE; + rtap_fields[RTAP_TXATTENUATION] = owl_true; rtap_position += RTAP_L_TXATTENUATION ; break ; case RTAP_TXATTENUATIONDB: - rtap_fields[RTAP_TXATTENUATIONDB] = TRUE; + rtap_fields[RTAP_TXATTENUATIONDB] = owl_true; rtap_position += RTAP_L_TXATTENUATIONDB ; break ; case RTAP_TXATTENUATIONDBM: - rtap_fields[RTAP_TXATTENUATIONDBM] = TRUE; + rtap_fields[RTAP_TXATTENUATIONDBM] = owl_true; rtap_position += RTAP_L_TXATTENUATIONDBM ; break ; case RTAP_ANTENNA: - rtap_fields[RTAP_ANTENNA] = TRUE; + rtap_fields[RTAP_ANTENNA] = owl_true; rtap_position += RTAP_L_ANTENNA ; break ; case RTAP_ANTENNASIGNALDB: - rtap_fields[RTAP_ANTENNASIGNALDB] = TRUE; + rtap_fields[RTAP_ANTENNASIGNALDB] = owl_true; rtap_position += RTAP_L_ANTENNASIGNALDB ; break ; case RTAP_ANTENNANOISEDB: - rtap_fields[RTAP_ANTENNANOISEDB] = TRUE; + rtap_fields[RTAP_ANTENNANOISEDB] = owl_true; rtap_position += RTAP_L_ANTENNANOISEDB ; break ; case RTAP_FCS: - rtap_fields[RTAP_FCS] = TRUE; + rtap_fields[RTAP_FCS] = owl_true; rtap_position += RTAP_L_FCS ; break ; } @@ -1458,10 +1459,10 @@ void print_usage() program_name, program_name, DEFAULT_CONFIG_FILE, - LOC_REQUEST_DEFAULT_PORT, - AGGREGATE_DEFAULT_PORT, - DEFAULT_AUTOCALIBRATION_REQUEST_PORT, - DEFAULT_AUTOCALIBRATION_PORT, + OWL_DEFAULT_REQUEST_PORT, + OWL_DEFAULT_LISTENER_PORT, + OWL_DEFAULT_AUTOCALIBRATION_REQUEST_PORT, + OWL_DEFAULT_AUTOCALIBRATION_PORT, DEFAULT_AUTOCALIBRATION_HELLO_DELAY, DEFAULT_AUTOCALIBRATION_DELAY, DEFAULT_AUTOCALIBRATION_NBPKT diff --git a/owlps-positioning/src/owlps-positioning.cc b/owlps-positioning/src/owlps-positioning.cc index 9103c21..4e12f77 100644 --- a/owlps-positioning/src/owlps-positioning.cc +++ b/owlps-positioning/src/owlps-positioning.cc @@ -30,7 +30,7 @@ int main(int argc, char **argv) sigaction(SIGTERM, &action, NULL) ; /* Run! */ - owl_run = TRUE ; + owl_run = owl_true ; Positioning positioning ; /* Clean */ diff --git a/owlps-positioning/src/userinterface.cc b/owlps-positioning/src/userinterface.cc index 867dbcc..ab296b0 100644 --- a/owlps-positioning/src/userinterface.cc +++ b/owlps-positioning/src/userinterface.cc @@ -149,7 +149,7 @@ void UserInterface::fill_input_options() ("input.csv-file,C", po::value(), "CSV file to use for input (when input.medium = CSV).") ("input.udp-port,p", po::value() - ->default_value(POSITIONER_DEFAULT_PORT), + ->default_value(OWL_DEFAULT_AGGREGATION_PORT), "Port on which the UDP socket listens (when input.medium = UDP).") ; @@ -263,7 +263,7 @@ void UserInterface::fill_output_options() ("output.udp-host", po::value(), "Host to which the UDP data is sent (when output.medium = UDP).") ("output.udp-port", po::value() - ->default_value(MOBILE_DEFAULT_PORT), + ->default_value(OWL_DEFAULT_RESULT_PORT), "Port on which the UDP data is sent (when output.medium = UDP).") ("output.tcpevaal-host", po::value() ->default_value(DEFAULT_TCPEVAAL_HOST), From e77ad8fb0f8f1d4a4a2b610b8fc0b6977b3db7f4 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Sat, 20 Aug 2011 19:56:17 +0200 Subject: [PATCH 16/46] Add owlps-udp-to-http This new module allows to get the results sent by the positioning server with HTTP queries. See the heading comment in owlps-udp-to-http.c. --- Makefile | 16 +- owlps-udp-to-http/Makefile | 110 ++++++++ owlps-udp-to-http/owlps-udp-to-http.c | 385 ++++++++++++++++++++++++++ 3 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 owlps-udp-to-http/Makefile create mode 100644 owlps-udp-to-http/owlps-udp-to-http.c diff --git a/Makefile b/Makefile index 51d916b..cb3fca4 100644 --- a/Makefile +++ b/Makefile @@ -6,16 +6,19 @@ owlps-client \ owlps-listener \ owlps-aggregator \ + owlps-udp-to-http \ owlps-positioning \ install \ install-owlps-client \ install-owlps-listener \ install-owlps-aggregator \ + install-owlps-udp-to-http \ install-owlps-positioning \ uninstall \ uninstall-owlps-client \ uninstall-owlps-listener \ uninstall-owlps-aggregator \ + uninstall-owlps-udp-to-http \ uninstall-owlps-positioning ## Compilation ## @@ -30,7 +33,8 @@ c: \ libowlps-resultreader-udp \ owlps-client \ owlps-listener \ - owlps-aggregator + owlps-aggregator \ + owlps-udp-to-http libowlps: @make -C $@ @@ -44,6 +48,8 @@ owlps-listener: libowlps libowlps-client @make -C $@ owlps-aggregator: libowlps @make -C $@ +owlps-udp-to-http: libowlps libowlps-resultreader-udp + @make -C $@ owlps-positioning: libowlps @make -C $@ @@ -55,6 +61,7 @@ install : \ install-owlps-client \ install-owlps-listener \ install-owlps-aggregator \ + install-owlps-udp-to-http \ install-owlps-positioning install-libowlps: @@ -65,6 +72,8 @@ install-owlps-listener: install-libowlps @make -C $(subst install-,,$@) install install-owlps-aggregator: install-libowlps @make -C $(subst install-,,$@) install +install-owlps-udp-to-http: install-libowlps + @make -C $(subst install-,,$@) install install-owlps-positioning: install-libowlps @make -C $(subst install-,,$@) install @@ -76,6 +85,7 @@ uninstall : \ uninstall-owlps-client \ uninstall-owlps-listener \ uninstall-owlps-aggregator \ + uninstall-owlps-udp-to-http \ uninstall-owlps-positioning uninstall-libowlps: @@ -86,6 +96,8 @@ uninstall-owlps-listener: @make -C $(subst uninstall-,,$@) uninstall uninstall-owlps-aggregator: @make -C $(subst uninstall-,,$@) uninstall +uninstall-owlps-udp-to-http: + @make -C $(subst uninstall-,,$@) uninstall uninstall-owlps-positioning: @make -C $(subst uninstall-,,$@) uninstall @@ -99,6 +111,7 @@ clean : @make -C owlps-client clean @make -C owlps-listener clean @make -C owlps-aggregator clean + @make -C owlps-udp-to-http clean @make -C owlps-positioning clean purge : @@ -108,6 +121,7 @@ purge : @make -C owlps-client purge @make -C owlps-listener purge @make -C owlps-aggregator purge + @make -C owlps-udp-to-http purge @make -C owlps-positioning purge diff --git a/owlps-udp-to-http/Makefile b/owlps-udp-to-http/Makefile new file mode 100644 index 0000000..817f7ae --- /dev/null +++ b/owlps-udp-to-http/Makefile @@ -0,0 +1,110 @@ +# Source version +ifndef OWLPS_VERSION + OWLPS_VERSION := $(shell git describe 2>/dev/null || echo 'UNKNOWN_VERSION') +endif + +# Répertoire d'installation +PREFIX=/usr/local +INSTALL_DIR= $(PREFIX)/bin +INSTALL_LIB= $(PREFIX)/lib +INSTALL_INC= $(PREFIX)/include +INSTALL_MAN= $(PREFIX)/share/man + +# Compilateur +COLORGCC := $(shell which colorgcc >/dev/null 2>&1 ; echo $$?) +ifeq ($(COLORGCC), 0) + CC = colorgcc +endif + +# Commandes d'installation et de désinstallation +RM = rm -f +CP = cp + +# Cible +TARGET = owlps-udp-to-http +HEADER = + +# Flags +LIBOWLPS_DIR = ../libowlps +LIBOWLPSRESULTREADERUDP_DIR = ../libowlps-resultreader-udp +CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ + -I$(LIBOWLPS_DIR) -I$(LIBOWLPSRESULTREADERUDP_DIR) +#CFLAGS += -g -O0 +DEPFLAGS = -MMD +XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) +PICFLAG = -fPIC +OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" +OWLPSFLAGS += -D DEBUG +LIBS = -L$(LIBOWLPS_DIR) -lowlps \ + -L$(LIBOWLPSRESULTREADERUDP_DIR) -lowlps-resultreader-udp + +OS := $(shell uname) +ifeq ("$(OS)", "Linux") + LIBS += -lrt +endif + +STATIC_LIBS = + + +## Cibles de compilation standard ## + +.PHONY : all dynamic static install uninstall clean purge help + +dynamic : $(TARGET) +static : $(TARGET).static +all : dynamic static + +# Cancel implicit make rule +%: %.c + +%: %.o + $(CC) $(LDFLAGS) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ $(LIBS) +%.static: %.o + $(CC) $(STRIPFLAGS) $(XCFLAGS) -o $@ $^ \ + $(LDFLAGS) $(LIBS) $(STATIC_LIBS) -static +%.o: %.c $(HEADER) + $(CC) $(XCFLAGS) $(OWLPSFLAGS) -c $< + + +## Installation / désinstallation ## + +install : $(TARGET) + @$(CP) $(TARGET) $(INSTALL_DIR) + @cd $(INSTALL_DIR) ; chown root:root $(TARGET) ; chmod 755 $(TARGET) + +install-static : $(TARGET).static + @$(CP) $(TARGET).static $(INSTALL_DIR) + @cd $(INSTALL_DIR) ; chown root:root $(TARGET).static ; chmod 755 $(TARGET).static + +uninstall : + @$(RM) $(INSTALL_DIR)/{$(TARGET),$(TARGET).static} + + +## Nettoyage ## + +clean : + @$(RM) *~ *.o *.d + +purge : clean + @$(RM) $(TARGET) $(TARGET).static + + +## Aide ## + +help : + @echo "Bibliothèques nécessaires à la compilation :" + @echo " libowlps1.0 (fournie)" + @echo " libowlps-resultreader-udp1.0 (fournie)" + @echo + @echo "Cibles possibles :" + @echo " $(TARGET) (cible par défaut) : Compile le programme \ +$(TARGET)." + @echo " $(TARGET).static : Compile le programme $(TARGET).static \ +(version sans lien dynamique)." + @echo " install : Installe le programme $(TARGET)." + @echo " uninstall : Désinstalle le programme $(TARGET)." + @echo " clean : Supprime les fichiers temporaires." + @echo " purge : Supprime le résultat de la compilation." + @echo + @echo "Note : l'installation se fait dans l'arborescence $(PREFIX). \ +Modifiez la variable PREFIX du Makefile pour changer ce comportement." diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c new file mode 100644 index 0000000..98cae3a --- /dev/null +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -0,0 +1,385 @@ +/* + * This program listens for results sent by OwlPS Positioning on a UDP + * socket, and listens for a client on a TCP socket. The client is + * expected to send an HTTP GET request, with the request string as the + * first variable value (the variable name does not matter). + * For example, a correct request is detected if you load + * http://localhost:8080/?request=ReadSimpleResults + * (assuming the host running this program is localhost). + * + * The UDP listening port is the port on which OwlPS Positioning sends + * result by default. + * The TCP listening port is 8080. + * + * Only the last result read from the positioning server, for each + * mobile, is memorised and provided to the HTTP client. + * + * The only HTTP request currently implemented is "ReadSimpleResults". + * Answer in case of error: + * SimpleResults;NOK + * Normal answer: + * SimpleResults;OK;Nb_results;Result_1;…;Result_n + * Nb_results is the number of results in the answer. + * Result_i follows this format: + * Mobile_MAC;Algorithm_name;X;Y;Z;Area_name + * + * If a unknown request is received, the answer format is: + * UnknownRequest;NOK + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define TCP_PORT 8080 +#define NB_CONNECTIONS 1 +#define CLIENT_MESSAGE_STRLEN 2500 + +#define SIMPLE_RESULTS_ID 1 +#define SIMPLE_RESULTS_REQUEST "ReadSimpleResults" +#define SIMPLE_RESULTS_ANSWER "SimpleResults" +#define CLIENT_REQUEST_STRLEN 21 + +#ifndef OWLPS_VERSION +# define OWLPS_VERSION "unknown version" +#endif // OWLPS_VERSION + +#define ANSWER_HEADER \ + "HTTP/1.1 200 OK\n" \ + "Date: Sat, 01 Jan 0001 00:00:01 GMT\n" \ + "Server: OwlPS UDP-to-HTTP ["OWLPS_VERSION"]\n" \ + "Access-Control-Allow-Origin: *\n" \ + "Connection: close\n" \ + "Content-Type: text/html\n" \ + "\n" + + +typedef struct _results_list +{ + owl_result *result ; + struct _results_list *next ; +} results_list ; + + +void store_result(owl_result *result) ; +void* tcp_server(void *NULL_value) ; +int +extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], + char *client_message) ; +void free_results_list(void) ; + + +char *program_name = NULL ; + +results_list *results = NULL ; +unsigned int nb_results = 0 ; +sem_t lock_results ; + + +int main(int argc, char *argv[]) +{ + struct sigaction action ; // Signal handler structure + int ret = 0 ; // Program return value + pthread_t tcp_server_thread ; + owl_result *result ; + int udp_sockfd ; + + program_name = argv[0] ; + owl_run = owl_true ; + + /* Set up signal handlers */ + action.sa_flags = 0 ; + sigemptyset(&action.sa_mask) ; + action.sa_handler = owl_sigint_handler ; + sigaction(SIGINT, &action, NULL) ; + action.sa_handler = owl_sigterm_handler ; + sigaction(SIGTERM, &action, NULL) ; + + /* Set up the semaphore */ + sem_init(&lock_results, 0, 1) ; + + /* Open the UDP socket */ + udp_sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; + if (udp_sockfd < 0) + { + ret = 1 ; + goto exit ; + } + + /* Launch the TCP thread */ + ret = pthread_create(&tcp_server_thread, NULL, + &tcp_server, NULL) ; + if (ret) + { + perror("Cannot create the TCP server thread") ; + ret = 1 ; + goto exit ; + } + + /* UDP read loop */ + while (owl_run) + { + result = owl_receive_position(udp_sockfd) ; + if (result == NULL) + { + ret = 1 ; + goto exit ; + } + owl_print_result(result) ; + store_result(result) ; + printf("--------------\n") ; + } + + /* Stop the TCP thread */ + if (pthread_join(tcp_server_thread, NULL)) + perror("Cannot join the TCP server thread") ; + + /* Cleaning */ + exit: + free_results_list() ; + sem_destroy(&lock_results) ; + close(udp_sockfd) ; + + printf("%s: end.\n", program_name) ; + return ret ; +} + + +void store_result(owl_result *new_result) +{ + sem_wait(&lock_results) ; + + // The results' list does not exist yet + if (! results) + { + results = malloc(sizeof(results_list)) ; + ++nb_results ; + results->result = new_result ; + results->next = NULL ; + } + + // The results' list contains at least 1 element + else + { + // Search for an existing result with the same mobile's MAC + results_list *res = results ; + while (res != NULL) + { + char *mac = res->result->mobile_mac_addr ; + if (strncmp(mac, new_result->mobile_mac_addr, + OWL_ETHER_ADDR_STRLEN) == 0) + break ; + res = res->next ; + } + + if (res == NULL) // Not found, adding an element + { + res = malloc(sizeof(results_list)) ; + ++nb_results ; + res->next = results ; + results = res ; + } + else // Found, clearing it + owl_free_result(res->result) ; + + res->result = new_result ; + } + + sem_post(&lock_results) ; +} + + +void* tcp_server(void *NULL_value) +{ + int tcp_sockfd, newsockfd ; + socklen_t client_len ; + struct sockaddr_in server_addr, client_addr ; + ssize_t nbytes ; // recv/send return value + char client_message[CLIENT_MESSAGE_STRLEN] ; + char client_request[CLIENT_REQUEST_STRLEN] ; + int request_id ; + char *answer ; // Answer to send to the client + size_t answer_hdr_len = strlen(ANSWER_HEADER) ; + size_t answer_len ; // Total size of the answer + + tcp_sockfd = socket(AF_INET, SOCK_STREAM, 0) ; + if (tcp_sockfd < 0) + { + perror("Error opening the TCP socket") ; + exit(1) ; + } + pthread_cleanup_push(&owl_close_fd, &tcp_sockfd) ; + + bzero((char *) &server_addr, sizeof(server_addr)) ; + server_addr.sin_family = AF_INET ; + server_addr.sin_addr.s_addr = INADDR_ANY ; + server_addr.sin_port = htons(TCP_PORT) ; + + if (bind(tcp_sockfd, (struct sockaddr *) &server_addr, + sizeof(server_addr)) < 0) + { + perror("Error binding the TCP socket") ; + exit(1) ; + } + + listen(tcp_sockfd, NB_CONNECTIONS) ; + client_len = sizeof(client_addr) ; + + // Prepare the answer, assuming there is only 1 result (an error + // message will also fit) + answer = malloc(answer_hdr_len + OWL_CSV_RESULT_STRLEN) ; + strncpy(answer, ANSWER_HEADER, answer_hdr_len) ; + + while (owl_run) + { + newsockfd = accept(tcp_sockfd, + (struct sockaddr*) &client_addr, &client_len) ; + if (newsockfd < 0) + { + perror("Error accepting a connection on the TCP socket") ; + continue ; + } + + nbytes = + recv(newsockfd, client_message, CLIENT_MESSAGE_STRLEN, 0) ; + if (nbytes < 0) + { + perror("Error reading from the TCP socket") ; + close(newsockfd) ; + continue ; + } + + client_message[nbytes] = '\0' ; + +#ifdef DEBUG + printf("Got a message from the client:\n" + "\"%s\"\n", client_message) ; +#endif // DEBUG + + answer_len = answer_hdr_len ; + request_id = + extract_request_from_message(client_request, client_message) ; + switch (request_id) + { + case SIMPLE_RESULTS_ID: + strncpy(answer + answer_len, SIMPLE_RESULTS_ANSWER, + strlen(SIMPLE_RESULTS_ANSWER)) ; + answer_len += strlen(SIMPLE_RESULTS_ANSWER) ; + + sem_wait(&lock_results) ; + + if (! results) + { + char answer_end[] = ";NOK;NoResult" ; + strncpy(answer + answer_len, answer_end, + strlen(answer_end)) ; + answer_len += strlen(answer_end) ; + } + + else + { + results_list *result ; + char answer_begin[10] ; + size_t answer_begin_len, answer_buf_len ; + + snprintf(answer_begin, 10, ";OK;%u", nb_results) ; + answer_begin_len = strlen(answer_begin) ; + strncpy(answer + answer_len, answer_begin, + answer_begin_len) ; + answer_len += answer_begin_len ; + + answer_buf_len = + answer_len + answer_begin_len + + nb_results * OWL_CSV_RESULT_STRLEN ; + answer = realloc(answer, answer_buf_len) ; + + result = results ; + while (result != NULL) + { + char result_str[OWL_CSV_RESULT_STRLEN] ; + size_t result_len ; + owl_result_to_csv(result_str, result->result) ; + result_len = strlen(result_str) ; + answer[answer_len++] = ';' ; + strncpy(answer + answer_len, result_str, + result_len) ; + answer_len += result_len ; + result = result->next ; + } + } + + sem_post(&lock_results) ; + + break ; + + default: + { + char answer_end[] = "UnknownRequest;NOK" ; + strncpy(answer + answer_hdr_len, answer_end, + strlen(answer_end)) ; + answer_len += strlen(answer_end) ; + } + } + + answer[answer_len] = '\0' ; + printf("Answer to send:\n\"%s\"\n", answer) ; + + nbytes = send(newsockfd, answer, answer_len, 0) ; + if (nbytes < 0) + perror("Error sending answer to the TCP socket") ; + + close(newsockfd) ; + } + + /* Cleaning */ + // Close tcp_sockfd + pthread_cleanup_pop(1) ; + free(answer) ; + + pthread_exit(NULL_value) ; +} + + +int +extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], + char *client_message) +{ + char *token ; + + token = strchr(client_message, '=') ; + if (! token) + return 0 ; + ++token ; + token = strsep(&token, " ") ; + + if (strncmp(SIMPLE_RESULTS_REQUEST, token, + strlen(SIMPLE_RESULTS_REQUEST)) == 0) + { + strncpy(client_request, SIMPLE_RESULTS_REQUEST, + CLIENT_REQUEST_STRLEN) ; + return SIMPLE_RESULTS_ID ; + } + + return 0 ; // No known request found +} + + +void free_results_list() +{ + results_list *ptr = results ; + while (ptr != NULL) + { + owl_free_result(ptr->result) ; + ptr = ptr->next ; + } + nb_results = 0 ; +} From 3626a21f9999312bba98f9469bca169707b4ad4a Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 12:01:59 +0200 Subject: [PATCH 17/46] [lib-result] Add simplified CSV format functions Add functions owl_result_to_csv_simple() and owl_algorithm_result_to_csv_simple(), that convert an owl_result and an owl_algorithm_result to a CSV string, in a simplified format. --- .../libowlps-resultreader-udp.c | 58 +++++++++++++++++++ .../owlps-resultreader-udp.h | 5 ++ 2 files changed, 63 insertions(+) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index c384309..b35eb0a 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -269,6 +269,64 @@ owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], } +/* + * Converts an owl_result back to a CSV string, in a simplified format. + * Only the *first* algorithm in the result's algorithm list will be + * included in the string. + * 'dst' must be an allocated string of at least OWL_CSV_RESULT_STRLEN + * characters. + * + * CSV format: + * Mobile_MAC;First_algorithm + * First_algorithm is the first algorithm in src->results. Its format + * is documented in owl_algorithm_result_to_csv_simple(). + */ +void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], + const owl_result *const src) +{ + size_t dst_len ; + char algo_str[OWL_CSV_ALGORITHM_RESULT_STRLEN] ; + + assert(src) ; + + strncpy(dst, src->mobile_mac_addr, OWL_ETHER_ADDR_STRLEN) ; + dst[OWL_ETHER_ADDR_STRLEN - 1] = ';' ; + dst_len = OWL_ETHER_ADDR_STRLEN ; + + if (! src->results) + return ; + + owl_algorithm_result_to_csv_simple(algo_str, src->results) ; + strncpy(dst + dst_len, algo_str, OWL_CSV_ALGORITHM_RESULT_STRLEN) ; +} + + +/* + * Converts an owl_algorithm_result back to a CSV string, in a + * simplified format. + * 'dst' must be an allocated string of at least + * OWL_CSV_ALGORITHM_RESULT_STRLEN characters. + * + * CSV format: + * X;Y;Z;Area_name + * Area_name is the name of the area or room in which the mobile is (may + * be empty). + */ +void owl_algorithm_result_to_csv_simple +(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], + const owl_algorithm_result *const src) +{ + assert(src) ; + + snprintf(dst, OWL_CSV_ALGORITHM_RESULT_STRLEN, + "%f;%f;%f;%s", + src->x, + src->y, + src->z, + src->area ? src->area : "") ; +} + + /* * Prints an owl_result to the given stream. */ diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index 8e730e3..0142388 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -63,6 +63,11 @@ void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], void owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], const owl_algorithm_result *const src) ; +void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], + const owl_result *const src) ; +void owl_algorithm_result_to_csv_simple +(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], + const owl_algorithm_result *const src) ; void owl_fprint_result(FILE *stream, const owl_result *const src) ; void owl_fprint_algorithm_result(FILE *stream, From 6160eb9c986f924b56d82fe9ba2bb310b3eae6d1 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 13:30:29 +0200 Subject: [PATCH 18/46] [UDP-HTTP] Makefile: fix static Add missing -pthread. --- owlps-udp-to-http/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owlps-udp-to-http/Makefile b/owlps-udp-to-http/Makefile index 817f7ae..fa93d9b 100644 --- a/owlps-udp-to-http/Makefile +++ b/owlps-udp-to-http/Makefile @@ -35,7 +35,7 @@ XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) PICFLAG = -fPIC OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" OWLPSFLAGS += -D DEBUG -LIBS = -L$(LIBOWLPS_DIR) -lowlps \ +LIBS = -pthread -L$(LIBOWLPS_DIR) -lowlps \ -L$(LIBOWLPSRESULTREADERUDP_DIR) -lowlps-resultreader-udp OS := $(shell uname) From ee02f26d8a3fb139ae6750192cc3a79db272ef25 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 13:32:02 +0200 Subject: [PATCH 19/46] [UDP-HTTP] Change and fix SimpleResults format Use owl_result_to_csv_simple() from libowlps-result. --- owlps-udp-to-http/owlps-udp-to-http.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 98cae3a..0048abc 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -16,12 +16,14 @@ * * The only HTTP request currently implemented is "ReadSimpleResults". * Answer in case of error: - * SimpleResults;NOK + * SimpleResults;NOK;Explanation * Normal answer: * SimpleResults;OK;Nb_results;Result_1;…;Result_n - * Nb_results is the number of results in the answer. + * Nb_results is the number of results in the answer (number of mobiles). * Result_i follows this format: - * Mobile_MAC;Algorithm_name;X;Y;Z;Area_name + * Mobile_MAC;X;Y;Z;Area_name + * Area_name is the name of the area or room in which the mobile is (may + * be empty). * * If a unknown request is received, the answer format is: * UnknownRequest;NOK @@ -298,7 +300,7 @@ void* tcp_server(void *NULL_value) answer_len += answer_begin_len ; answer_buf_len = - answer_len + answer_begin_len + + answer_len + nb_results * OWL_CSV_RESULT_STRLEN ; answer = realloc(answer, answer_buf_len) ; @@ -307,7 +309,7 @@ void* tcp_server(void *NULL_value) { char result_str[OWL_CSV_RESULT_STRLEN] ; size_t result_len ; - owl_result_to_csv(result_str, result->result) ; + owl_result_to_csv_simple(result_str, result->result) ; result_len = strlen(result_str) ; answer[answer_len++] = ';' ; strncpy(answer + answer_len, result_str, From 177bd6284c6d02be4fa363209a23b490b5c465b4 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 15:11:55 +0200 Subject: [PATCH 20/46] [lib-result] #define "simple CSV" string sizes owlps.h: #define the coordinate string size. --- .../libowlps-resultreader-udp.c | 17 ++++---- .../owlps-resultreader-udp.h | 40 ++++++++++++++----- libowlps/owlps.h | 2 + 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index b35eb0a..7105065 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -273,19 +273,19 @@ owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], * Converts an owl_result back to a CSV string, in a simplified format. * Only the *first* algorithm in the result's algorithm list will be * included in the string. - * 'dst' must be an allocated string of at least OWL_CSV_RESULT_STRLEN - * characters. + * 'dst' must be an allocated string of at least + * OWL_CSV_RESULT_SIMPLE_STRLEN characters. * * CSV format: * Mobile_MAC;First_algorithm * First_algorithm is the first algorithm in src->results. Its format * is documented in owl_algorithm_result_to_csv_simple(). */ -void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], +void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_SIMPLE_STRLEN], const owl_result *const src) { size_t dst_len ; - char algo_str[OWL_CSV_ALGORITHM_RESULT_STRLEN] ; + char algo_str[OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN] ; assert(src) ; @@ -297,7 +297,8 @@ void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], return ; owl_algorithm_result_to_csv_simple(algo_str, src->results) ; - strncpy(dst + dst_len, algo_str, OWL_CSV_ALGORITHM_RESULT_STRLEN) ; + strncpy(dst + dst_len, algo_str, + OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN) ; } @@ -305,7 +306,7 @@ void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], * Converts an owl_algorithm_result back to a CSV string, in a * simplified format. * 'dst' must be an allocated string of at least - * OWL_CSV_ALGORITHM_RESULT_STRLEN characters. + * OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN characters. * * CSV format: * X;Y;Z;Area_name @@ -313,12 +314,12 @@ void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], * be empty). */ void owl_algorithm_result_to_csv_simple -(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], +(char dst[OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN], const owl_algorithm_result *const src) { assert(src) ; - snprintf(dst, OWL_CSV_ALGORITHM_RESULT_STRLEN, + snprintf(dst, OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN, "%f;%f;%f;%s", src->x, src->y, diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index 0142388..f72fd0d 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -15,15 +15,35 @@ /* Maximum size of a result CSV string sent by OwlPS Positioning. * Request's information: - * = 18 (MAC) + 2 (type) + 22 (timestamp) = 42 + ';' = 43 - * Plus, for each algorithm, about 60 characters (say 100, as the length - * of the algorithm and area names can vary, 101 with the ';'). - * Let's keep room for 10 algorithms : - * 10×101 + 43 = 1053 characters. + * MAC, request type (2 chars), timestamp, ';' + * Plus, for each algorithm: + * Name, three coordinates, error (we assume the same size as the + * coordinates), area name, ';' + * Let's define OWL_NB_ALGORITHMS as the number of implemented + * algorithms (this is ugly). */ -#define OWL_CSV_RESULT_REQUEST_STRLEN 43 -#define OWL_CSV_ALGORITHM_RESULT_STRLEN 101 -#define OWL_CSV_RESULT_STRLEN 1053 +#define OWL_NB_ALGORITHMS 10 +#define OWL_CSV_RESULT_REQUEST_STRLEN \ + (OWL_ETHER_ADDR_STRLEN + OWL_TIMESTAMP_STRLEN + 3) +#define OWL_CSV_ALGORITHM_RESULT_STRLEN \ + (OWL_ALGORITHM_STRLEN + 4 * OWL_COORDINATE_STRLEN + \ + OWL_AREA_STRLEN + 1) +#define OWL_CSV_RESULT_STRLEN \ + (OWL_CSV_RESULT_REQUEST_STRLEN + \ + OWL_NB_ALGORITHMS * OWL_CSV_ALGORITHM_RESULT_STRLEN + 1) + +/* Same thing, but for the simplified CSV strings created by + * *_to_csv_simple(). + * Request's information is only the MAC address. + * For the algorithm: + * = 12 characters per coordinate + OWL_AREA_STRLEN + */ +#define OWL_CSV_RESULT_REQUEST_SIMPLE_STRLEN OWL_ETHER_ADDR_STRLEN +#define OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN \ + (3 * OWL_COORDINATE_STRLEN + OWL_AREA_STRLEN + 1) +#define OWL_CSV_RESULT_SIMPLE_STRLEN \ + (OWL_CSV_RESULT_REQUEST_SIMPLE_STRLEN + \ + OWL_NB_ALGORITHMS * OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN + 1) /* Linked list of algorithms' results. @@ -63,10 +83,10 @@ void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], void owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], const owl_algorithm_result *const src) ; -void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_STRLEN], +void owl_result_to_csv_simple(char dst[OWL_CSV_RESULT_SIMPLE_STRLEN], const owl_result *const src) ; void owl_algorithm_result_to_csv_simple -(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], +(char dst[OWL_CSV_ALGORITHM_RESULT_SIMPLE_STRLEN], const owl_algorithm_result *const src) ; void owl_fprint_result(FILE *stream, const owl_result *const src) ; diff --git a/libowlps/owlps.h b/libowlps/owlps.h index 5eb6526..7a90c61 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -164,6 +164,8 @@ typedef struct _owl_autocalibration_order #define OWL_ALGORITHM_STRLEN 31 // Maximum length of an area name (including '\0') #define OWL_AREA_STRLEN 31 +// Maximum length of a coordinate X, Y or Z (including '\0') +#define OWL_COORDINATE_STRLEN 16 /* Global variables */ From c2aaa3af15b18f3a66e285960935fcbefe872983 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 15:07:56 +0200 Subject: [PATCH 21/46] [UDP-HTTP] Big refactoring Create owlps-udp-to-http.h, rename variables, refactor functions, etc. --- owlps-udp-to-http/owlps-udp-to-http.c | 297 ++++++++++++++------------ owlps-udp-to-http/owlps-udp-to-http.h | 48 +++++ 2 files changed, 204 insertions(+), 141 deletions(-) create mode 100644 owlps-udp-to-http/owlps-udp-to-http.h diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 0048abc..521417a 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -29,7 +29,7 @@ * UnknownRequest;NOK */ -#include +#include "owlps-udp-to-http.h" #include #include @@ -42,58 +42,25 @@ #include -#define TCP_PORT 8080 -#define NB_CONNECTIONS 1 -#define CLIENT_MESSAGE_STRLEN 2500 - -#define SIMPLE_RESULTS_ID 1 -#define SIMPLE_RESULTS_REQUEST "ReadSimpleResults" -#define SIMPLE_RESULTS_ANSWER "SimpleResults" -#define CLIENT_REQUEST_STRLEN 21 - -#ifndef OWLPS_VERSION -# define OWLPS_VERSION "unknown version" -#endif // OWLPS_VERSION - -#define ANSWER_HEADER \ - "HTTP/1.1 200 OK\n" \ - "Date: Sat, 01 Jan 0001 00:00:01 GMT\n" \ - "Server: OwlPS UDP-to-HTTP ["OWLPS_VERSION"]\n" \ - "Access-Control-Allow-Origin: *\n" \ - "Connection: close\n" \ - "Content-Type: text/html\n" \ - "\n" - - -typedef struct _results_list -{ - owl_result *result ; - struct _results_list *next ; -} results_list ; - - -void store_result(owl_result *result) ; -void* tcp_server(void *NULL_value) ; -int -extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], - char *client_message) ; -void free_results_list(void) ; - - char *program_name = NULL ; results_list *results = NULL ; unsigned int nb_results = 0 ; sem_t lock_results ; +int udp_sockfd = -1 ; +int tcp_sockfd = -1 ; + +char *answer = NULL ; // Answer to send to the client +size_t answer_strlen = 0 ; // Total size of the answer string +size_t answer_buflen = 0 ; // Size of the answer allocated buffer + int main(int argc, char *argv[]) { struct sigaction action ; // Signal handler structure int ret = 0 ; // Program return value pthread_t tcp_server_thread ; - owl_result *result ; - int udp_sockfd ; program_name = argv[0] ; owl_run = owl_true ; @@ -109,14 +76,6 @@ int main(int argc, char *argv[]) /* Set up the semaphore */ sem_init(&lock_results, 0, 1) ; - /* Open the UDP socket */ - udp_sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; - if (udp_sockfd < 0) - { - ret = 1 ; - goto exit ; - } - /* Launch the TCP thread */ ret = pthread_create(&tcp_server_thread, NULL, &tcp_server, NULL) ; @@ -127,19 +86,8 @@ int main(int argc, char *argv[]) goto exit ; } - /* UDP read loop */ - while (owl_run) - { - result = owl_receive_position(udp_sockfd) ; - if (result == NULL) - { - ret = 1 ; - goto exit ; - } - owl_print_result(result) ; - store_result(result) ; - printf("--------------\n") ; - } + /* Main loop */ + ret = receive_udp() ; /* Stop the TCP thread */ if (pthread_join(tcp_server_thread, NULL)) @@ -147,15 +95,54 @@ int main(int argc, char *argv[]) /* Cleaning */ exit: + if (tcp_sockfd >= 0) + if (close(tcp_sockfd)) + perror("Error closing the TCP socket") ; + if (udp_sockfd >= 0) + if (close(udp_sockfd)) + perror("Error closing the UDP socket") ; + + free(answer) ; free_results_list() ; sem_destroy(&lock_results) ; - close(udp_sockfd) ; printf("%s: end.\n", program_name) ; return ret ; } +/* + * Opens the UDP socket and reads from it the results sent by OwlPS + * Positioning. + * Returns a non-zero value in case of error. + */ +int receive_udp() +{ + owl_result *result ; + + /* Open the UDP socket */ + udp_sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; + if (udp_sockfd < 0) + return 1 ; + + /* UDP read loop */ + while (owl_run) + { + result = owl_receive_position(udp_sockfd) ; + if (result == NULL) + return 1 ; + owl_print_result(result) ; + store_result(result) ; + printf("--------------\n") ; + } + + return 0 ; +} + + +/* + * Adds a new owl_result to the results' list. + */ void store_result(owl_result *new_result) { sem_wait(&lock_results) ; @@ -200,18 +187,18 @@ void store_result(owl_result *new_result) } +/* + * Opens the TCP socket and wait for requests from HTTP clients. + */ void* tcp_server(void *NULL_value) { - int tcp_sockfd, newsockfd ; + int newsockfd ; socklen_t client_len ; struct sockaddr_in server_addr, client_addr ; ssize_t nbytes ; // recv/send return value char client_message[CLIENT_MESSAGE_STRLEN] ; char client_request[CLIENT_REQUEST_STRLEN] ; int request_id ; - char *answer ; // Answer to send to the client - size_t answer_hdr_len = strlen(ANSWER_HEADER) ; - size_t answer_len ; // Total size of the answer tcp_sockfd = socket(AF_INET, SOCK_STREAM, 0) ; if (tcp_sockfd < 0) @@ -219,7 +206,6 @@ void* tcp_server(void *NULL_value) perror("Error opening the TCP socket") ; exit(1) ; } - pthread_cleanup_push(&owl_close_fd, &tcp_sockfd) ; bzero((char *) &server_addr, sizeof(server_addr)) ; server_addr.sin_family = AF_INET ; @@ -236,10 +222,11 @@ void* tcp_server(void *NULL_value) listen(tcp_sockfd, NB_CONNECTIONS) ; client_len = sizeof(client_addr) ; - // Prepare the answer, assuming there is only 1 result (an error + // Prepare the answer, assuming there is only 1 full result (an error // message will also fit) - answer = malloc(answer_hdr_len + OWL_CSV_RESULT_STRLEN) ; - strncpy(answer, ANSWER_HEADER, answer_hdr_len) ; + answer_buflen = ANSWER_HDR_STRLEN + OWL_CSV_RESULT_STRLEN ; + answer = malloc(answer_buflen) ; + strncpy(answer, ANSWER_HDR, ANSWER_HDR_STRLEN) ; while (owl_run) { @@ -259,7 +246,6 @@ void* tcp_server(void *NULL_value) close(newsockfd) ; continue ; } - client_message[nbytes] = '\0' ; #ifdef DEBUG @@ -267,86 +253,22 @@ void* tcp_server(void *NULL_value) "\"%s\"\n", client_message) ; #endif // DEBUG - answer_len = answer_hdr_len ; request_id = extract_request_from_message(client_request, client_message) ; - switch (request_id) - { - case SIMPLE_RESULTS_ID: - strncpy(answer + answer_len, SIMPLE_RESULTS_ANSWER, - strlen(SIMPLE_RESULTS_ANSWER)) ; - answer_len += strlen(SIMPLE_RESULTS_ANSWER) ; + prepare_answer(request_id) ; - sem_wait(&lock_results) ; - - if (! results) - { - char answer_end[] = ";NOK;NoResult" ; - strncpy(answer + answer_len, answer_end, - strlen(answer_end)) ; - answer_len += strlen(answer_end) ; - } - - else - { - results_list *result ; - char answer_begin[10] ; - size_t answer_begin_len, answer_buf_len ; - - snprintf(answer_begin, 10, ";OK;%u", nb_results) ; - answer_begin_len = strlen(answer_begin) ; - strncpy(answer + answer_len, answer_begin, - answer_begin_len) ; - answer_len += answer_begin_len ; - - answer_buf_len = - answer_len + - nb_results * OWL_CSV_RESULT_STRLEN ; - answer = realloc(answer, answer_buf_len) ; - - result = results ; - while (result != NULL) - { - char result_str[OWL_CSV_RESULT_STRLEN] ; - size_t result_len ; - owl_result_to_csv_simple(result_str, result->result) ; - result_len = strlen(result_str) ; - answer[answer_len++] = ';' ; - strncpy(answer + answer_len, result_str, - result_len) ; - answer_len += result_len ; - result = result->next ; - } - } - - sem_post(&lock_results) ; - - break ; - - default: - { - char answer_end[] = "UnknownRequest;NOK" ; - strncpy(answer + answer_hdr_len, answer_end, - strlen(answer_end)) ; - answer_len += strlen(answer_end) ; - } - } - - answer[answer_len] = '\0' ; +#ifdef DEBUG printf("Answer to send:\n\"%s\"\n", answer) ; +#endif // DEBUG - nbytes = send(newsockfd, answer, answer_len, 0) ; + /* Send the answer */ + nbytes = send(newsockfd, answer, answer_strlen, 0) ; if (nbytes < 0) perror("Error sending answer to the TCP socket") ; close(newsockfd) ; } - /* Cleaning */ - // Close tcp_sockfd - pthread_cleanup_pop(1) ; - free(answer) ; - pthread_exit(NULL_value) ; } @@ -375,6 +297,99 @@ extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], } +/* + * Prepare the answer string to send to the TCP client. + */ +void prepare_answer(int request_id) +{ + // Reset the answer's length: + answer_strlen = ANSWER_HDR_STRLEN ; + + switch (request_id) + { + case SIMPLE_RESULTS_ID: + strncpy(answer + answer_strlen, SIMPLE_RESULTS_ANSWER, + strlen(SIMPLE_RESULTS_ANSWER)) ; + answer_strlen += strlen(SIMPLE_RESULTS_ANSWER) ; + + sem_wait(&lock_results) ; + + if (! results) + { + char answer_end[] = ";NOK;NoResult" ; + strncpy(answer + answer_strlen, answer_end, + strlen(answer_end)) ; + answer_strlen += strlen(answer_end) ; + } + + else + { + results_list *result ; + char answer_begin[10] ; + size_t answer_begin_len ; + + snprintf(answer_begin, 10, ";OK;%u", nb_results) ; + answer_begin_len = strlen(answer_begin) ; + strncpy(answer + answer_strlen, answer_begin, + answer_begin_len) ; + answer_strlen += answer_begin_len ; + + realloc_answer(answer_strlen + + nb_results * OWL_CSV_RESULT_SIMPLE_STRLEN) ; + + result = results ; + while (result != NULL) + { + char result_str[OWL_CSV_RESULT_SIMPLE_STRLEN] ; + size_t result_len ; + owl_result_to_csv_simple(result_str, result->result) ; + result_len = strlen(result_str) ; + answer[answer_strlen++] = ';' ; + strncpy(answer + answer_strlen, result_str, + result_len) ; + answer_strlen += result_len ; + result = result->next ; + } + } + + sem_post(&lock_results) ; + + break ; + + default: + { + char answer_end[] = "UnknownRequest;NOK" ; + strncpy(answer + ANSWER_HDR_STRLEN, answer_end, + strlen(answer_end)) ; + answer_strlen += strlen(answer_end) ; + } + } + + answer[answer_strlen] = '\0' ; +} + + +/* + * Realloc the answer buffer to the if needed: grows it if new_size is + * greater than the current size, shrink it if the current size is + * greater than the double of new_size. + */ +void realloc_answer(size_t new_size) +{ + if (new_size > answer_buflen) + answer_buflen = new_size ; + else if (answer_buflen / 2 >= new_size) + answer_buflen /= 2 ; + else + return ; + + answer = realloc(answer, answer_buflen) ; +} + + +/* + * Frees the memory allocated for the results' list. + */ void free_results_list() { results_list *ptr = results ; diff --git a/owlps-udp-to-http/owlps-udp-to-http.h b/owlps-udp-to-http/owlps-udp-to-http.h new file mode 100644 index 0000000..aebfb3e --- /dev/null +++ b/owlps-udp-to-http/owlps-udp-to-http.h @@ -0,0 +1,48 @@ +#ifndef _OWLPS_UDP_TO_HTTP_H_ +#define _OWLPS_UDP_TO_HTTP_H_ + +#include + +#define TCP_PORT 8080 +#define NB_CONNECTIONS 1 +#define CLIENT_MESSAGE_STRLEN 2500 + +#define SIMPLE_RESULTS_ID 1 +#define SIMPLE_RESULTS_REQUEST "ReadSimpleResults" +#define SIMPLE_RESULTS_ANSWER "SimpleResults" +#define CLIENT_REQUEST_STRLEN 21 + +#ifndef OWLPS_VERSION +# define OWLPS_VERSION "unknown version" +#endif // OWLPS_VERSION + +#define ANSWER_HDR \ + "HTTP/1.1 200 OK\n" \ + "Date: Sat, 01 Jan 0001 00:00:01 GMT\n" \ + "Server: OwlPS UDP-to-HTTP ["OWLPS_VERSION"]\n" \ + "Access-Control-Allow-Origin: *\n" \ + "Connection: close\n" \ + "Content-Type: text/html\n" \ + "\n" +#define ANSWER_HDR_STRLEN strlen(ANSWER_HDR) + + +typedef struct _results_list +{ + owl_result *result ; + struct _results_list *next ; +} results_list ; + + +int receive_udp(void) ; +void store_result(owl_result *result) ; +void* tcp_server(void *NULL_value) ; +int +extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], + char *client_message) ; +void prepare_answer(int request_id) ; +void realloc_answer(size_t new_size) ; +void free_results_list(void) ; + + +#endif // _OWLPS_UDP_TO_HTTP_H_ From 73494defe6d32843ed8efa9f74b020513b6cc65e Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 17:05:45 +0200 Subject: [PATCH 22/46] [lib-result] Add the number of algorithms Add the field nb_results to owl_result, and change the functions to handle it. --- .../libowlps-resultreader-udp.c | 30 +++++++++++++------ .../owlps-resultreader-udp.h | 1 + 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index 7105065..61284b4 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -54,7 +54,6 @@ owl_result* owl_fill_result(char *csv) { char *csv_field = NULL ; owl_result *result = NULL ; - int nb_algorithms = 0 ; result = malloc(sizeof(owl_result)) ; memset(result, 0, sizeof(*result)) ; @@ -111,13 +110,13 @@ owl_result* owl_fill_result(char *csv) if (current_algo == NULL) { fprintf(stderr, "Error reading the algorithm #%d!\n", - nb_algorithms) ; + result->nb_results + 1) ; break ; } // Insert the current algorithm at the begining of the list current_algo->next = result->results ; result->results = current_algo ; - ++nb_algorithms ; + ++result->nb_results ; } while (csv) ; @@ -132,7 +131,7 @@ owl_result* owl_fill_result(char *csv) /* * Splits the 'csv' string, stores the fields in a new * owl_algorithm_result, and returns a pointer to it (or NULL - * in case of error). + * in case of error). * * Note that the new owl_algorithm_result is allocated with malloc() * and must be deleted using free(). @@ -217,6 +216,11 @@ owl_algorithm_result* owl_fill_algorithm_result(char **csv) * Converts an owl_result back to a CSV string. * 'dst' must be an allocated string of at least OWL_CSV_RESULT_STRLEN * characters. + * + * CSV format: + * Mobile_MAC;Request_type;Request_timestamp;Nb_algo;Algo_1;…;Algo_n + * Nb_algo is the number of algorithms in the result. + * The format of Algo_i is documented in owl_algorithm_result_to_csv(). */ void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], const owl_result *const src) @@ -228,10 +232,11 @@ void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], owl_timestamp_to_string(timestamp_str, src->mobile_timestamp) ; snprintf(dst, OWL_CSV_RESULT_REQUEST_STRLEN, - "%s;%"PRIu8";%s", + "%s;%"PRIu8";%s;%u", src->mobile_mac_addr, src->request_type, - timestamp_str) ; + timestamp_str, + src->nb_results) ; dst_len = strlen(dst) ; owl_algorithm_result *algo = src->results ; @@ -251,6 +256,13 @@ void owl_result_to_csv(char dst[OWL_CSV_RESULT_STRLEN], * Converts an owl_algorithm_result back to a CSV string. * 'dst' must be an allocated string of at least * OWL_CSV_ALGORITHM_RESULT_STRLEN characters. + * + * CSV format: + * Algorithm_name;X;Y;Z;Error;Area_name + * Error is the distance from the true coordinates of the mobile, if + * known; if unknown, Error is set to -1. + * Area_name is the name of the area or room in which the mobile is (may + * be empty). */ void owl_algorithm_result_to_csv(char dst[OWL_CSV_ALGORITHM_RESULT_STRLEN], @@ -342,12 +354,12 @@ void owl_fprint_result(FILE *stream, const owl_result *const src) "Mobile MAC: %s\n" "Request type: %"PRIu8"\n" "Mobile timestamp: %s\n" - "Results:\n" + "%u results:\n" , src->mobile_mac_addr, src->request_type, - timestamp_str - ) ; + timestamp_str, + src->nb_results) ; owl_algorithm_result *algo = src->results ; while (algo) diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader-udp/owlps-resultreader-udp.h index f72fd0d..8d0d08e 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.h +++ b/libowlps-resultreader-udp/owlps-resultreader-udp.h @@ -70,6 +70,7 @@ typedef struct _owl_result char *mobile_mac_addr ; uint8_t request_type ; owl_timestamp mobile_timestamp ; + unsigned int nb_results ; owl_algorithm_result *results ; } owl_result ; From adc05b98c0c3a1cb3fa791278dc0426130198f75 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 19:26:21 +0200 Subject: [PATCH 23/46] [UDP-HTTP] Handle new request "ReadResults" --- owlps-udp-to-http/owlps-udp-to-http.c | 85 +++++++++++++++++++++++++-- owlps-udp-to-http/owlps-udp-to-http.h | 5 +- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 521417a..f0aec91 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -14,7 +14,29 @@ * Only the last result read from the positioning server, for each * mobile, is memorised and provided to the HTTP client. * - * The only HTTP request currently implemented is "ReadSimpleResults". + * The HTTP requests currently implemented are listed bellow. + * + * ** Request "ReadResults" ** + * Answer in case of error: + * Results;NOK;Explanation + * Normal answer: + * Results;OK;Nb_results;Result_1;…;Result_n + * Nb_results is the number of results in the answer (number of mobiles). + * Result_i follows this format: + * Mobile_MAC;Request_type;Request_timestamp;Nb_algo;Algo_1;…;Algo_n + * Nb_algo is the number of algorithms in the result. + * Algo_i follows this format: + * Algorithm_name;X;Y;Z;Error;Area_name + * Error is the distance from the true coordinates of the mobile, if + * known; if unknown, Error is set to -1. + * Area_name is the name of the area or room in which the mobile is (may + * be empty). + * + * ** Unknown request ** + * If a unknown request is received, the answer format is: + * UnknownRequest;NOK + * + * ** Request "ReadSimpleResults" ** * Answer in case of error: * SimpleResults;NOK;Explanation * Normal answer: @@ -24,9 +46,6 @@ * Mobile_MAC;X;Y;Z;Area_name * Area_name is the name of the area or room in which the mobile is (may * be empty). - * - * If a unknown request is received, the answer format is: - * UnknownRequest;NOK */ #include "owlps-udp-to-http.h" @@ -293,6 +312,14 @@ extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], return SIMPLE_RESULTS_ID ; } + if (strncmp(RESULTS_REQUEST, token, + strlen(RESULTS_REQUEST)) == 0) + { + strncpy(client_request, RESULTS_REQUEST, + CLIENT_REQUEST_STRLEN) ; + return RESULTS_ID ; + } + return 0 ; // No known request found } @@ -307,6 +334,56 @@ void prepare_answer(int request_id) switch (request_id) { + case RESULTS_ID: + strncpy(answer + answer_strlen, RESULTS_ANSWER, + strlen(RESULTS_ANSWER)) ; + answer_strlen += strlen(RESULTS_ANSWER) ; + + sem_wait(&lock_results) ; + + if (! results) + { + char answer_end[] = ";NOK;NoResult" ; + strncpy(answer + answer_strlen, answer_end, + strlen(answer_end)) ; + answer_strlen += strlen(answer_end) ; + } + + else + { + results_list *result ; + char answer_begin[10] ; + size_t answer_begin_len ; + + snprintf(answer_begin, 10, ";OK;%u", nb_results) ; + answer_begin_len = strlen(answer_begin) ; + strncpy(answer + answer_strlen, answer_begin, + answer_begin_len) ; + answer_strlen += answer_begin_len ; + + realloc_answer(answer_strlen + + nb_results * OWL_CSV_RESULT_STRLEN) ; + + result = results ; + while (result != NULL) + { + char result_str[OWL_CSV_RESULT_STRLEN] ; + size_t result_len ; + owl_result_to_csv(result_str, result->result) ; + result_len = strlen(result_str) ; + answer[answer_strlen++] = ';' ; + assert(answer_strlennext ; + } + } + + sem_post(&lock_results) ; + + break ; + case SIMPLE_RESULTS_ID: strncpy(answer + answer_strlen, SIMPLE_RESULTS_ANSWER, strlen(SIMPLE_RESULTS_ANSWER)) ; diff --git a/owlps-udp-to-http/owlps-udp-to-http.h b/owlps-udp-to-http/owlps-udp-to-http.h index aebfb3e..46b2538 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.h +++ b/owlps-udp-to-http/owlps-udp-to-http.h @@ -7,10 +7,13 @@ #define NB_CONNECTIONS 1 #define CLIENT_MESSAGE_STRLEN 2500 +#define CLIENT_REQUEST_STRLEN 21 #define SIMPLE_RESULTS_ID 1 #define SIMPLE_RESULTS_REQUEST "ReadSimpleResults" #define SIMPLE_RESULTS_ANSWER "SimpleResults" -#define CLIENT_REQUEST_STRLEN 21 +#define RESULTS_ID 2 +#define RESULTS_REQUEST "ReadResults" +#define RESULTS_ANSWER "Results" #ifndef OWLPS_VERSION # define OWLPS_VERSION "unknown version" From 632858155a2e392889475386c60a2d136e63f9b6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 17:07:02 +0200 Subject: [PATCH 24/46] [UDP-HTTP] Cancel the TCP thread Cancel the TCP thread before to join it, because of the blocking recv() call. --- owlps-udp-to-http/owlps-udp-to-http.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index f0aec91..3879726 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -109,11 +109,15 @@ int main(int argc, char *argv[]) ret = receive_udp() ; /* Stop the TCP thread */ + // We must cancel the thread because it can be blocked on the + // recv() call: + if (pthread_cancel(tcp_server_thread)) + perror("Cannot cancel the TCP server thread") ; if (pthread_join(tcp_server_thread, NULL)) perror("Cannot join the TCP server thread") ; - /* Cleaning */ exit: + /* Close sockets */ if (tcp_sockfd >= 0) if (close(tcp_sockfd)) perror("Error closing the TCP socket") ; @@ -121,6 +125,7 @@ int main(int argc, char *argv[]) if (close(udp_sockfd)) perror("Error closing the UDP socket") ; + /* Last cleaning */ free(answer) ; free_results_list() ; sem_destroy(&lock_results) ; From 8cc05d718c163faefb6512cd66741dd84487bd8b Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 17:14:16 +0200 Subject: [PATCH 25/46] [lib-result] Do not perror() if owl_run is false owl_receive_position() do not print the error message when owl_run is false. This is to avoid an error message when a program is stopped. --- libowlps-resultreader-udp/libowlps-resultreader-udp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader-udp/libowlps-resultreader-udp.c index 61284b4..96d2320 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader-udp/libowlps-resultreader-udp.c @@ -13,10 +13,13 @@ /* * Receives a result from the socket of file descriptor 'sockfd', fills * an owl_result structure with the received information, and returns a - * pointer to it (or NULL in case of error). + * pointer to it. * * Note that the new owl_result is allocated with malloc() and must be * deleted using free(). + * + * In case of error, a message is printed, except if owl_run (from + * libowlps) is false, and NULL is returned. */ owl_result* owl_receive_position(int sockfd) { @@ -28,7 +31,8 @@ owl_result* owl_receive_position(int sockfd) if (nread <= 0) { - perror("No request received from listener") ; + if (owl_run) + perror("No request received from listener") ; return NULL ; } From a7bfa7eb07cd2472a2442a68bda8f3e6654349c9 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 17:18:28 +0200 Subject: [PATCH 26/46] [UDP-HTTP] Display a message if called with args This is mainly to avoid a "unused variable" message when compiling. --- owlps-udp-to-http/owlps-udp-to-http.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 3879726..9b55e42 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -84,6 +84,10 @@ int main(int argc, char *argv[]) program_name = argv[0] ; owl_run = owl_true ; + if (argc > 1) + fprintf(stderr, + "Sorry, this program does not take any argument yet.\n") ; + /* Set up signal handlers */ action.sa_flags = 0 ; sigemptyset(&action.sa_mask) ; From 46e295dc0929ab90e85e0ad055b344075d3ab1f2 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 20:40:16 +0200 Subject: [PATCH 27/46] [UDP-HTTP] Init. TCP socket in a separate function Initialise the TCP socket in the new function. This is to avoid exit() in the thread (memory leak). --- owlps-udp-to-http/owlps-udp-to-http.c | 40 +++++++++++++++++++-------- owlps-udp-to-http/owlps-udp-to-http.h | 1 + 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 9b55e42..5fb9cd8 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -99,6 +99,11 @@ int main(int argc, char *argv[]) /* Set up the semaphore */ sem_init(&lock_results, 0, 1) ; + /* Prepare the TCP socket */ + ret = init_tcp_socket() ; + if (ret) + goto exit ; + /* Launch the TCP thread */ ret = pthread_create(&tcp_server_thread, NULL, &tcp_server, NULL) ; @@ -216,23 +221,18 @@ void store_result(owl_result *new_result) /* - * Opens the TCP socket and wait for requests from HTTP clients. + * Opens the TCP socket. + * Returns a non-zero value in case of error. */ -void* tcp_server(void *NULL_value) +int init_tcp_socket() { - int newsockfd ; - socklen_t client_len ; - struct sockaddr_in server_addr, client_addr ; - ssize_t nbytes ; // recv/send return value - char client_message[CLIENT_MESSAGE_STRLEN] ; - char client_request[CLIENT_REQUEST_STRLEN] ; - int request_id ; + struct sockaddr_in server_addr ; tcp_sockfd = socket(AF_INET, SOCK_STREAM, 0) ; if (tcp_sockfd < 0) { perror("Error opening the TCP socket") ; - exit(1) ; + return tcp_sockfd ; } bzero((char *) &server_addr, sizeof(server_addr)) ; @@ -240,13 +240,31 @@ void* tcp_server(void *NULL_value) server_addr.sin_addr.s_addr = INADDR_ANY ; server_addr.sin_port = htons(TCP_PORT) ; + if (bind(tcp_sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("Error binding the TCP socket") ; - exit(1) ; + return -1 ; } + return 0 ; +} + + +/* + * Waits for requests from HTTP clients. + */ +void* tcp_server(void *NULL_value) +{ + int newsockfd ; + socklen_t client_len ; + struct sockaddr_in client_addr ; + ssize_t nbytes ; // recv/send return value + char client_message[CLIENT_MESSAGE_STRLEN] ; + char client_request[CLIENT_REQUEST_STRLEN] ; + int request_id ; + listen(tcp_sockfd, NB_CONNECTIONS) ; client_len = sizeof(client_addr) ; diff --git a/owlps-udp-to-http/owlps-udp-to-http.h b/owlps-udp-to-http/owlps-udp-to-http.h index 46b2538..f504fce 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.h +++ b/owlps-udp-to-http/owlps-udp-to-http.h @@ -39,6 +39,7 @@ typedef struct _results_list int receive_udp(void) ; void store_result(owl_result *result) ; +int init_tcp_socket(void) ; void* tcp_server(void *NULL_value) ; int extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], From 3a38d2bc1eaa1aa21eacf97ce2430d95df871f27 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 21:38:58 +0200 Subject: [PATCH 28/46] [UDP-HTTP] Improve free_results_list() --- owlps-udp-to-http/owlps-udp-to-http.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 5fb9cd8..c83125d 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -496,11 +496,14 @@ void realloc_answer(size_t new_size) */ void free_results_list() { - results_list *ptr = results ; - while (ptr != NULL) + while (results != NULL) { - owl_free_result(ptr->result) ; - ptr = ptr->next ; + owl_free_result(results->result) ; + results = results->next ; +#ifndef NDEBUG + --nb_results ; +#endif // NDEBUG } + assert(nb_results == 0) ; nb_results = 0 ; } From 32d8a04ad5e415d78d178c3f5759c969c7369083 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 21:51:30 +0200 Subject: [PATCH 29/46] [lib-result] Rename to libowlps-resultreader After all, this is not really UDP-specific. --- Makefile | 12 ++++++------ .../Makefile | 4 ++-- .../libowlps-resultreader.c | 2 +- .../owlps-resultreader-udp.c | 2 +- .../owlps-resultreader.h | 0 owlps-udp-to-http/Makefile | 8 ++++---- owlps-udp-to-http/owlps-udp-to-http.h | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) rename {libowlps-resultreader-udp => libowlps-resultreader}/Makefile (95%) rename libowlps-resultreader-udp/libowlps-resultreader-udp.c => libowlps-resultreader/libowlps-resultreader.c (99%) rename {libowlps-resultreader-udp => libowlps-resultreader}/owlps-resultreader-udp.c (96%) rename libowlps-resultreader-udp/owlps-resultreader-udp.h => libowlps-resultreader/owlps-resultreader.h (100%) diff --git a/Makefile b/Makefile index cb3fca4..f361a9f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ all c clean purge help \ libowlps \ libowlps-client \ - libowlps-resultreader-udp \ + libowlps-resultreader \ owlps-client \ owlps-listener \ owlps-aggregator \ @@ -30,7 +30,7 @@ all: \ c: \ libowlps \ libowlps-client \ - libowlps-resultreader-udp \ + libowlps-resultreader \ owlps-client \ owlps-listener \ owlps-aggregator \ @@ -40,7 +40,7 @@ libowlps: @make -C $@ libowlps-client: libowlps @make -C $@ -libowlps-resultreader-udp: libowlps +libowlps-resultreader: libowlps @make -C $@ owlps-client: libowlps libowlps-client @make -C $@ @@ -48,7 +48,7 @@ owlps-listener: libowlps libowlps-client @make -C $@ owlps-aggregator: libowlps @make -C $@ -owlps-udp-to-http: libowlps libowlps-resultreader-udp +owlps-udp-to-http: libowlps libowlps-resultreader @make -C $@ owlps-positioning: libowlps @make -C $@ @@ -107,7 +107,7 @@ uninstall-owlps-positioning: clean : @make -C libowlps clean @make -C libowlps-client clean - @make -C libowlps-resultreader-udp clean + @make -C libowlps-resultreader clean @make -C owlps-client clean @make -C owlps-listener clean @make -C owlps-aggregator clean @@ -117,7 +117,7 @@ clean : purge : @make -C libowlps purge @make -C libowlps-client purge - @make -C libowlps-resultreader-udp purge + @make -C libowlps-resultreader purge @make -C owlps-client purge @make -C owlps-listener purge @make -C owlps-aggregator purge diff --git a/libowlps-resultreader-udp/Makefile b/libowlps-resultreader/Makefile similarity index 95% rename from libowlps-resultreader-udp/Makefile rename to libowlps-resultreader/Makefile index 10b8b9d..14fd90f 100644 --- a/libowlps-resultreader-udp/Makefile +++ b/libowlps-resultreader/Makefile @@ -10,12 +10,12 @@ RANLIB = ranlib RM = rm -f # Variables générales -LIB_CIBLE = libowlps-resultreader-udp +LIB_CIBLE = libowlps-resultreader VERSION = 1.0 # Cibles à construire STATIC = $(LIB_CIBLE).a -HEADER = owlps-resultreader-udp.h +HEADER = owlps-resultreader.h EXAMPLE = owlps-resultreader-udp # Composition de la bibliothèque diff --git a/libowlps-resultreader-udp/libowlps-resultreader-udp.c b/libowlps-resultreader/libowlps-resultreader.c similarity index 99% rename from libowlps-resultreader-udp/libowlps-resultreader-udp.c rename to libowlps-resultreader/libowlps-resultreader.c index 96d2320..d3602ab 100644 --- a/libowlps-resultreader-udp/libowlps-resultreader-udp.c +++ b/libowlps-resultreader/libowlps-resultreader.c @@ -1,4 +1,4 @@ -#include "owlps-resultreader-udp.h" +#include "owlps-resultreader.h" #include #include diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.c b/libowlps-resultreader/owlps-resultreader-udp.c similarity index 96% rename from libowlps-resultreader-udp/owlps-resultreader-udp.c rename to libowlps-resultreader/owlps-resultreader-udp.c index e8bfbb2..d0476e1 100644 --- a/libowlps-resultreader-udp/owlps-resultreader-udp.c +++ b/libowlps-resultreader/owlps-resultreader-udp.c @@ -5,7 +5,7 @@ * (see the Makefile). */ -#include "owlps-resultreader-udp.h" +#include "owlps-resultreader.h" #include #include diff --git a/libowlps-resultreader-udp/owlps-resultreader-udp.h b/libowlps-resultreader/owlps-resultreader.h similarity index 100% rename from libowlps-resultreader-udp/owlps-resultreader-udp.h rename to libowlps-resultreader/owlps-resultreader.h diff --git a/owlps-udp-to-http/Makefile b/owlps-udp-to-http/Makefile index fa93d9b..afe8558 100644 --- a/owlps-udp-to-http/Makefile +++ b/owlps-udp-to-http/Makefile @@ -26,9 +26,9 @@ HEADER = # Flags LIBOWLPS_DIR = ../libowlps -LIBOWLPSRESULTREADERUDP_DIR = ../libowlps-resultreader-udp +LIBOWLPSRESULTREADER_DIR = ../libowlps-resultreader CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ - -I$(LIBOWLPS_DIR) -I$(LIBOWLPSRESULTREADERUDP_DIR) + -I$(LIBOWLPS_DIR) -I$(LIBOWLPSRESULTREADER_DIR) #CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) @@ -36,7 +36,7 @@ PICFLAG = -fPIC OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" OWLPSFLAGS += -D DEBUG LIBS = -pthread -L$(LIBOWLPS_DIR) -lowlps \ - -L$(LIBOWLPSRESULTREADERUDP_DIR) -lowlps-resultreader-udp + -L$(LIBOWLPSRESULTREADER_DIR) -lowlps-resultreader OS := $(shell uname) ifeq ("$(OS)", "Linux") @@ -94,7 +94,7 @@ purge : clean help : @echo "Bibliothèques nécessaires à la compilation :" @echo " libowlps1.0 (fournie)" - @echo " libowlps-resultreader-udp1.0 (fournie)" + @echo " libowlps-resultreader1.0 (fournie)" @echo @echo "Cibles possibles :" @echo " $(TARGET) (cible par défaut) : Compile le programme \ diff --git a/owlps-udp-to-http/owlps-udp-to-http.h b/owlps-udp-to-http/owlps-udp-to-http.h index f504fce..9ceb98a 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.h +++ b/owlps-udp-to-http/owlps-udp-to-http.h @@ -1,7 +1,7 @@ #ifndef _OWLPS_UDP_TO_HTTP_H_ #define _OWLPS_UDP_TO_HTTP_H_ -#include +#include #define TCP_PORT 8080 #define NB_CONNECTIONS 1 From ff17c92bfa34e5cd0a0399dac469c34dd2ab2e56 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Mon, 22 Aug 2011 22:23:17 +0200 Subject: [PATCH 30/46] [lib-client] Change the prefix for "owl_" Use the prefix "owl_" instead of "owlclient_". --- libowlps-client/libowlps-client.c | 36 +++++++++++++++---------------- libowlps-client/owlps-client.h | 30 +++++++++++++------------- owlps-client/owlps-client.c | 8 +++---- owlps-listener/owlps-listenerd.c | 32 +++++++++++++-------------- 4 files changed, 52 insertions(+), 54 deletions(-) diff --git a/libowlps-client/libowlps-client.c b/libowlps-client/libowlps-client.c index 4451097..ff44774 100644 --- a/libowlps-client/libowlps-client.c +++ b/libowlps-client/libowlps-client.c @@ -16,10 +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(const char *const dest_ip, - const uint_fast16_t dest_port, - struct sockaddr_in *const server, - const char *const iface) +int owl_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 ; @@ -34,7 +34,7 @@ int owlclient_create_trx_socket(const char *const dest_ip, // If we specified an interface name if (iface != NULL && iface[0] != '\0') - owlclient_use_iface(sockfd, iface) ; + owl_use_iface(sockfd, iface) ; return sockfd ; } @@ -42,7 +42,7 @@ int owlclient_create_trx_socket(const char *const dest_ip, /* Selects 'iface' as sending interface for the socket 'sockfd'. */ -void owlclient_use_iface(const int sockfd, const char *const iface) +void owl_use_iface(const int sockfd, const char *const iface) { #ifdef __GLIBC__ if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface, @@ -66,12 +66,12 @@ void owlclient_use_iface(const int sockfd, const char *const iface) * nb_pkt: number of packets to transmit. * delay: delay between two transmissions, in milliseconds. */ -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 owl_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 ; @@ -83,13 +83,13 @@ void owlclient_send_request(const int sockfd, #endif // DEBUG // Transmit first packet: - owlclient_send_packet(sockfd, server, packet, packet_size) ; + owl_send_packet(sockfd, server, packet, packet_size) ; // Transmit remaining packets (if any): for (i = 0 ; i < nb_pkt - 1 ; ++i) { usleep(delay * 1000) ; // Wait during the wanted delay - owlclient_send_packet(sockfd, server, packet, packet_size) ; + owl_send_packet(sockfd, server, packet, packet_size) ; } #ifdef DEBUG @@ -99,10 +99,10 @@ void owlclient_send_request(const int sockfd, -void owlclient_send_packet(const int sockfd, - const struct sockaddr_in *const server, - const void *const packet, - const uint_fast16_t packet_size) +void owl_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, diff --git a/libowlps-client/owlps-client.h b/libowlps-client/owlps-client.h index 210df38..8a206cd 100644 --- a/libowlps-client/owlps-client.h +++ b/libowlps-client/owlps-client.h @@ -14,21 +14,21 @@ /* Function headers */ -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) ; +int owl_create_trx_socket(const char *const dest_ip, + const uint_fast16_t dest_port, + struct sockaddr_in *const server, + const char *const iface) ; +void owl_use_iface(const int sockfd, const char *const iface) ; +void owl_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 owl_send_packet(const int sockfd, + const struct sockaddr_in *const server, + const void *const packet, + const uint_fast16_t packet_size) ; #endif // _LIBOWLPS_CLIENT_ diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index c630c3f..fdda899 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -373,8 +373,8 @@ void print_configuration() void create_socket() { sockfd = - owlclient_create_trx_socket(options.dest_ip, options.dest_port, - &server, options.iface) ; + owl_create_trx_socket(options.dest_ip, options.dest_port, + &server, options.iface) ; } @@ -443,8 +443,8 @@ void make_packet() void send_request() { - owlclient_send_request(sockfd, &server, packet, packet_size, - options.nb_pkt, options.delay) ; + owl_send_request(sockfd, &server, packet, packet_size, + options.nb_pkt, options.delay) ; } diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 739cdc1..23844d7 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -749,9 +749,8 @@ int capture() /* Open UDP socket to the aggregator */ aggregation_sockfd = - owlclient_create_trx_socket(GET_AGGREGATION_IP(), - GET_AGGREGATION_PORT(), - &aggregation_server, NULL) ; + owl_create_trx_socket(GET_AGGREGATION_IP(), GET_AGGREGATION_PORT(), + &aggregation_server, NULL) ; while (owl_run) // Capture one packet at time, and call read_packet() on it: @@ -1215,17 +1214,16 @@ void* autocalibrate_hello(void *NULL_value) fprintf(stderr, "Autocalibration Hello thread launched.\n") ; send_sockfd = - owlclient_create_trx_socket(GET_AGGREGATION_IP(), - GET_AUTOCALIBRATION_PORT(), - &serv, NULL) ; + owl_create_trx_socket(GET_AGGREGATION_IP(), + GET_AUTOCALIBRATION_PORT(), &serv, NULL) ; pthread_cleanup_push(&owl_close_fd, &send_sockfd) ; memcpy(&message.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ; while (owl_run) { - owlclient_send_packet(send_sockfd, &serv, - &message, sizeof(message)) ; + owl_send_packet(send_sockfd, &serv, + &message, sizeof(message)) ; sleep(GET_AUTOCALIBRATION_HELLO_DELAY()) ; } @@ -1250,10 +1248,10 @@ void* autocalibrate(void *NULL_value) // Socket to send autocalibration positioning requests autocalibration_send_sockfd = - owlclient_create_trx_socket(GET_AUTOCALIBRATION_IP(), - GET_AUTOCALIBRATION_REQUEST_PORT(), - &autocalibration_send_server, - GET_WIFI_IFACE()) ; + owl_create_trx_socket(GET_AUTOCALIBRATION_IP(), + GET_AUTOCALIBRATION_REQUEST_PORT(), + &autocalibration_send_server, + GET_WIFI_IFACE()) ; // Socket to receive orders from the aggregator listen_sockfd = @@ -1303,11 +1301,11 @@ void send_autocalibration_request() uint8_t *packet ; uint_fast16_t packet_size = make_packet(&packet) ; - owlclient_send_request(autocalibration_send_sockfd, - &autocalibration_send_server, - packet, packet_size, - GET_AUTOCALIBRATION_NBPKT(), - GET_AUTOCALIBRATION_DELAY()) ; + owl_send_request(autocalibration_send_sockfd, + &autocalibration_send_server, + packet, packet_size, + GET_AUTOCALIBRATION_NBPKT(), + GET_AUTOCALIBRATION_DELAY()) ; free(packet) ; } From a301c87c1d0b1905359366371e93c0815f99e507 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 23 Aug 2011 09:43:57 +0200 Subject: [PATCH 31/46] [Positioning] Fix segfault when ignoring AP RP This commit fixes a segfault that occurred in certain circumstances with the option positioning.radar-ignore-ap-reference-points activated. The bug was introduced with this option in 0da98cdb. --- owlps-positioning/src/stock.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/owlps-positioning/src/stock.cc b/owlps-positioning/src/stock.cc index e258180..5b7d7a4 100644 --- a/owlps-positioning/src/stock.cc +++ b/owlps-positioning/src/stock.cc @@ -678,7 +678,10 @@ closest_calibration_request(const Request &request) // No non-AP reference point was found, we are forced to consider // the AP reference points if (i == calibration_requests.end()) - ignore_aps = false ; + { + i = calibration_requests.begin() ; + ignore_aps = false ; + } } float distance = i->ss_square_distance(request) ; From 8f48a224824fc47ea926cbccace76475301f9b07 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 23 Aug 2011 21:48:59 +0200 Subject: [PATCH 32/46] [Listener] Fix config parsing memory leaks The configuration parsing function could call exit() (e.g. with -h, -V, or in case of error), implying a memory leak. This is fixed. Additionally, minor cleaning in the configuration functions. --- owlps-listener/owlps-listener.h | 12 ++--- owlps-listener/owlps-listenerd.c | 93 +++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index 7d5198d..e9a9bbd 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -164,14 +164,14 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ; /* Function headers */ -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) ; +int initialise_configuration(int argc, char **argv) ; +int parse_config_file(int argc, char **argv) ; +int parse_command_line(int argc, char **argv) ; +int parse_main_options(int argc, char **argv) ; #ifdef USE_PTHREAD -void parse_calibration_data(int argc, char **argv) ; +int parse_calibration_data(int argc, char **argv) ; #endif // USE_PTHREAD -void check_configuration(void) ; +int check_configuration(void) ; #ifdef DEBUG void print_configuration(void) ; #endif // DEBUG diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 23844d7..d2f67a6 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -50,7 +50,7 @@ owl_bool coordinates_provided = owl_false ; #endif // USE_PTHREAD #ifdef USE_CONFIG_FILE -cfg_t *cfg ; // Configuration structure +cfg_t *cfg = NULL ; // Configuration structure #else // USE_CONFIG_FILE /* If we do not use libconfuse, we declare a structure to store getopt @@ -119,11 +119,13 @@ int main(int argc, char *argv[]) autocalibration_hello_thread ; #endif // USE_PTHREAD - program_name = argv[0] ; - initialise_configuration(argc, argv) ; - owl_run = owl_true ; + program_name = argv[0] ; + ret = initialise_configuration(argc, argv) ; + if (! owl_run) + goto exit ; + /* Set up signal handlers */ action.sa_flags = 0 ; sigemptyset(&action.sa_mask) ; @@ -245,19 +247,38 @@ int main(int argc, char *argv[]) -void initialise_configuration(int argc, char **argv) +/* + * Read the configuration from both the command line and the + * configuration file. + * Returns an error code, or 0 in case of success. If the program should + * stop (because of a special option or a configuration error), owl_run + * is set to false. + */ +int initialise_configuration(int argc, char **argv) { - parse_config_file(argc, argv) ; - parse_command_line(argc, argv) ; - check_configuration() ; + int ret ; + + ret = parse_config_file(argc, argv) ; + if (! owl_run) + return ret ; + + ret = parse_command_line(argc, argv) ; + if (! owl_run) + return ret ; + + ret = check_configuration() ; + if (! owl_run) + return ret ; if (VERBOSE_INFO) print_configuration() ; + + return 0 ; } -void parse_config_file(int argc, char **argv) +int parse_config_file(int argc, char **argv) { #ifdef USE_CONFIG_FILE // If we use libconfuse, we declare options: @@ -343,10 +364,12 @@ void parse_config_file(int argc, char **argv) break ; case 'h' : print_usage() ; - exit(0) ; + owl_run = owl_false ; + return EXIT_SUCCESS ; case 'V' : print_version() ; - exit(0) ; + owl_run = owl_false ; + return EXIT_SUCCESS ; } } @@ -373,25 +396,37 @@ void parse_config_file(int argc, char **argv) "Error! Parsing of configuration file « %s » failed!\n", config_file) ; free(config_file) ; - exit(ERR_PARSING_CONFIG_FILE) ; + owl_run = owl_false ; + return ERR_PARSING_CONFIG_FILE ; } free(config_file) ; #endif // USE_CONFIG_FILE + + return 0 ; } -void parse_command_line(int argc, char **argv) +int parse_command_line(int argc, char **argv) { - parse_main_options(argc, argv) ; + int ret ; + + ret = parse_main_options(argc, argv) ; + if (! owl_run) + return ret ; + #ifdef USE_PTHREAD - parse_calibration_data(argc, argv) ; + ret = parse_calibration_data(argc, argv) ; + if (! owl_run) + return ret ; #endif // USE_PTHREAD + + return 0 ; } -void parse_main_options(int argc, char **argv) +int parse_main_options(int argc, char **argv) { int opt ; @@ -430,8 +465,6 @@ void parse_main_options(int argc, char **argv) break ; case 'f' : // Config file break ; // (already parsed) - case 'h' : // Usage - break ; // (already parsed) case 'H' : #ifdef USE_PTHREAD SET_AUTOCALIBRATION_HELLO_DELAY(strtol(optarg, NULL, 0)) ; @@ -483,22 +516,23 @@ void parse_main_options(int argc, char **argv) case 'v' : INCREMENT_VERBOSE() ; break ; - case 'V' : // Version - break ; // (already parsed) case 'w' : SET_WIFI_IFACE(optarg) ; break ; default : print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } } + + return 0 ; } #ifdef USE_PTHREAD -void parse_calibration_data(int argc, char **argv) +int parse_calibration_data(int argc, char **argv) { /* Parse remaining arguments (possible calibration data) */ if (argc - optind != 0) @@ -514,15 +548,18 @@ void parse_calibration_data(int argc, char **argv) else // Bad number of arguments { print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } } + + return 0 ; } #endif // USE_PTHREAD -void check_configuration() +int check_configuration() { switch (GET_MODE()) { @@ -533,7 +570,8 @@ void check_configuration() default : fprintf(stderr, "Error! Unknown mode « %c ».\n", (char) GET_MODE()) ; print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } if (GET_RTAP_IFACE()[0] == '\0') @@ -541,7 +579,8 @@ void check_configuration() fprintf(stderr, "Error! You must specify a radiotap interface" " for the capture.\n") ; print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } if (GET_WIFI_IFACE()[0] == '\0') @@ -611,6 +650,8 @@ void check_configuration() } } #endif // USE_PTHREAD + + return 0 ; } From 1a98cf44b2f1a31be6552edc8dd9253a9790c9c7 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 10:47:13 +0200 Subject: [PATCH 33/46] [Aggregator] Fix config parsing memory leaks Same thing as for the Listener: avoid using exit(), prefer return an int value instead. --- owlps-aggregator/owlps-aggregator.h | 8 ++-- owlps-aggregator/owlps-aggregatord.c | 72 ++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/owlps-aggregator/owlps-aggregator.h b/owlps-aggregator/owlps-aggregator.h index 930ce88..bf07eaf 100644 --- a/owlps-aggregator/owlps-aggregator.h +++ b/owlps-aggregator/owlps-aggregator.h @@ -86,10 +86,10 @@ typedef struct _ap_list /* Function headers */ -void initialise_configuration(int argc, char **argv) ; -void parse_config_file(int argc, char **argv) ; -void parse_command_line(int argc, char **argv) ; -void check_configuration(void) ; +int initialise_configuration(int argc, char **argv) ; +int parse_config_file(int argc, char **argv) ; +int parse_command_line(int argc, char **argv) ; +int check_configuration(void) ; int read_loop(int sockfd) ; void got_request(owl_captured_request request) ; diff --git a/owlps-aggregator/owlps-aggregatord.c b/owlps-aggregator/owlps-aggregatord.c index d357514..557a931 100644 --- a/owlps-aggregator/owlps-aggregatord.c +++ b/owlps-aggregator/owlps-aggregatord.c @@ -42,10 +42,14 @@ int main(int argc, char **argv) monitor_aps_thread, // APs monitoring thread autocalibration_hello_thread ; // Hello messages reception thread uint_fast16_t listening_port ; - int sockfd ; // UDP listening socket + int sockfd = -1 ; // UDP listening socket + + owl_run = owl_true ; program_name = argv[0] ; - initialise_configuration(argc, argv) ; + ret = initialise_configuration(argc, argv) ; + if (! owl_run) + goto exit ; /* Set up signal handlers */ action.sa_flags = 0 ; @@ -98,7 +102,6 @@ int main(int argc, char **argv) } } - owl_run = owl_true ; ret = read_loop(sockfd) ; /* Wait for the threads to terminate */ @@ -140,7 +143,8 @@ int main(int argc, char **argv) /* Last cleaning tasks */ exit: - close(sockfd) ; // Close socket + if (sockfd >= 0) + close(sockfd) ; // Close socket free_request_list() ; free_ap_list() ; cfg_free(cfg) ; // Clean configuration @@ -154,11 +158,28 @@ int main(int argc, char **argv) -void initialise_configuration(int argc, char **argv) +/* + * Read the configuration from both the command line and the + * configuration file. + * Returns an error code, or 0 in case of success. If the program should + * stop (because of a special option or a configuration error), owl_run + * is set to false. + */ +int initialise_configuration(int argc, char **argv) { - parse_config_file(argc, argv) ; - parse_command_line(argc, argv) ; - check_configuration() ; + int ret ; + + ret = parse_config_file(argc, argv) ; + if (! owl_run) + return ret ; + + ret = parse_command_line(argc, argv) ; + if (! owl_run) + return ret ; + + ret = check_configuration() ; + if (! owl_run) + return ret ; /* Configuration printing */ if (VERBOSE_INFO) @@ -166,10 +187,12 @@ void initialise_configuration(int argc, char **argv) fprintf(stderr, "Configuration:\n") ; cfg_print(cfg, stderr) ; } + + return 0 ; } -void parse_config_file(int argc, char **argv) +int parse_config_file(int argc, char **argv) { // Config file options for confuse cfg_opt_t opts[] = @@ -221,10 +244,12 @@ void parse_config_file(int argc, char **argv) break ; case 'h' : print_usage() ; - exit(0) ; + owl_run = owl_false ; + return EXIT_SUCCESS ; case 'V' : print_version() ; - exit(0) ; + owl_run = owl_false ; + return EXIT_SUCCESS ; } } @@ -250,13 +275,16 @@ void parse_config_file(int argc, char **argv) "Error! Parsing of configuration file « %s » failed!\n", config_file) ; free(config_file) ; - exit(ERR_PARSING_CONFIG_FILE) ; + owl_run = owl_false ; + return ERR_PARSING_CONFIG_FILE ; } free(config_file) ; + + return 0 ; } -void parse_command_line(int argc, char **argv) +int parse_command_line(int argc, char **argv) { int opt ; @@ -281,9 +309,6 @@ void parse_command_line(int argc, char **argv) break ; case 'f' : // Config file break ; // (already parsed) - case 'h' : - print_usage() ; - exit(0) ; case 'i' : cfg_setstr(cfg, "positioner_ip", optarg) ; break ; @@ -316,20 +341,24 @@ void parse_command_line(int argc, char **argv) break ; default : print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } } + + return 0 ; } -void check_configuration() +int check_configuration() { // output_file // if (cfg_getstr(cfg, "output_file")[0] == '\0') { fprintf(stderr, "Error! You must specify an output file.\n") ; print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } // listening_port // @@ -358,7 +387,8 @@ void check_configuration() fprintf(stderr, "Error! You must specify the IP address of the" " localisation server.\n") ; print_usage() ; - exit(ERR_BAD_USAGE) ; + owl_run = owl_false ; + return ERR_BAD_USAGE ; } // aggregate_timeout // @@ -405,6 +435,8 @@ void check_configuration() " failing back to the default value.\n") ; cfg_setint(cfg, "ap_check_interval", DEFAULT_AP_CHECK_INTERVAL) ; } + + return 0 ; } From b57bf543c7c53e9a41ec3c3441eb34191a7ba37a Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 11:41:07 +0200 Subject: [PATCH 34/46] [Positioning] Fix config parsing memory leaks Do not use exit() from UserInterface::print_information_and_exit_if_requested(), set owl_run to false instead. This function is renamed print_information(). --- owlps-positioning/src/owlps-positioning.cc | 34 ++++++++++++---------- owlps-positioning/src/userinterface.cc | 19 ++++++------ owlps-positioning/src/userinterface.hh | 2 +- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/owlps-positioning/src/owlps-positioning.cc b/owlps-positioning/src/owlps-positioning.cc index 4e12f77..d0807d3 100644 --- a/owlps-positioning/src/owlps-positioning.cc +++ b/owlps-positioning/src/owlps-positioning.cc @@ -14,27 +14,31 @@ using namespace std ; int main(int argc, char **argv) { + owl_run = owl_true ; + /* Read options & configuration */ delete new UserInterface(argc, argv) ; - /* Read input data */ - delete new InputDataReader() ; + if (owl_run) + { + /* Read input data */ + delete new InputDataReader() ; - /* Set up signal handlers */ - struct sigaction action ; - action.sa_flags = 0 ; - sigemptyset(&action.sa_mask) ; - action.sa_handler = owl_sigint_handler ; - sigaction(SIGINT, &action, NULL) ; - action.sa_handler = owl_sigterm_handler ; - sigaction(SIGTERM, &action, NULL) ; + /* Set up signal handlers */ + struct sigaction action ; + action.sa_flags = 0 ; + sigemptyset(&action.sa_mask) ; + action.sa_handler = owl_sigint_handler ; + sigaction(SIGINT, &action, NULL) ; + action.sa_handler = owl_sigterm_handler ; + sigaction(SIGTERM, &action, NULL) ; - /* Run! */ - owl_run = owl_true ; - Positioning positioning ; + /* Run! */ + Positioning positioning ; - /* Clean */ - Stock::clear() ; + /* Clean */ + Stock::clear() ; + } cerr << argv[0] << ": end." << endl ; return 0 ; diff --git a/owlps-positioning/src/userinterface.cc b/owlps-positioning/src/userinterface.cc index ab296b0..04fb535 100644 --- a/owlps-positioning/src/userinterface.cc +++ b/owlps-positioning/src/userinterface.cc @@ -293,7 +293,9 @@ void UserInterface::fill_misc_options() void UserInterface::parse_options() { parse_command_line() ; - print_information_and_exit_if_requested() ; + print_information() ; + if (! owl_run) + return ; parse_file() ; @@ -310,10 +312,12 @@ void UserInterface::parse_command_line() const } -void UserInterface::print_information_and_exit_if_requested() const +/** + * If information is printed, owl_run is set to false, to indicate that + * the program should stop. + */ +void UserInterface::print_information() const { - bool exit_program = false ; - // Print version if requested if (Configuration::is_configured("version")) { @@ -326,18 +330,15 @@ void UserInterface::print_information_and_exit_if_requested() const "unknown version" #endif // OWLPS_VERSION << ".\n" ; - exit_program = true ; + owl_run = owl_false ; // Tell main() to exit } // Print usage if requested if (Configuration::is_configured("help")) { cout << *cli_options ; - exit_program = true ; + owl_run = owl_false ; // Tell main() to exit } - - if (exit_program) - exit(0) ; } diff --git a/owlps-positioning/src/userinterface.hh b/owlps-positioning/src/userinterface.hh index 91c21cd..8a23420 100644 --- a/owlps-positioning/src/userinterface.hh +++ b/owlps-positioning/src/userinterface.hh @@ -37,7 +37,7 @@ protected: void parse_file(void) const ; /// Prints usage and/or version information if requested by the user - void print_information_and_exit_if_requested(void) const ; + void print_information(void) const ; //@} public: From d2f0ad78e5285455ce40cd80d62aca6e3ea7bcb6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 10:28:54 +0200 Subject: [PATCH 35/46] Makefile: allow to define the make command In the global Makefile, allow to redefine the 'make' command with the variable MAKE. This is useful on *BSD: gmake MAKE=gmake --- Makefile | 76 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index f361a9f..335f549 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +ifndef MAKE + MAKE = make +endif + .PHONY: \ all c clean purge help \ libowlps \ @@ -37,21 +41,21 @@ c: \ owlps-udp-to-http libowlps: - @make -C $@ + @$(MAKE) -C $@ libowlps-client: libowlps - @make -C $@ + @$(MAKE) -C $@ libowlps-resultreader: libowlps - @make -C $@ + @$(MAKE) -C $@ owlps-client: libowlps libowlps-client - @make -C $@ + @$(MAKE) -C $@ owlps-listener: libowlps libowlps-client - @make -C $@ + @$(MAKE) -C $@ owlps-aggregator: libowlps - @make -C $@ + @$(MAKE) -C $@ owlps-udp-to-http: libowlps libowlps-resultreader - @make -C $@ + @$(MAKE) -C $@ owlps-positioning: libowlps - @make -C $@ + @$(MAKE) -C $@ ## Installation ## @@ -65,17 +69,17 @@ install : \ install-owlps-positioning install-libowlps: - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install install-owlps-client: install-libowlps - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install install-owlps-listener: install-libowlps - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install install-owlps-aggregator: install-libowlps - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install install-owlps-udp-to-http: install-libowlps - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install install-owlps-positioning: install-libowlps - @make -C $(subst install-,,$@) install + @$(MAKE) -C $(subst install-,,$@) install ## Uninstallation ## @@ -89,40 +93,40 @@ uninstall : \ uninstall-owlps-positioning uninstall-libowlps: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall uninstall-owlps-client: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall uninstall-owlps-listener: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall uninstall-owlps-aggregator: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall uninstall-owlps-udp-to-http: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall uninstall-owlps-positioning: - @make -C $(subst uninstall-,,$@) uninstall + @$(MAKE) -C $(subst uninstall-,,$@) uninstall ## Cleaning ## clean : - @make -C libowlps clean - @make -C libowlps-client clean - @make -C libowlps-resultreader clean - @make -C owlps-client clean - @make -C owlps-listener clean - @make -C owlps-aggregator clean - @make -C owlps-udp-to-http clean - @make -C owlps-positioning clean + @$(MAKE) -C libowlps clean + @$(MAKE) -C libowlps-client clean + @$(MAKE) -C libowlps-resultreader clean + @$(MAKE) -C owlps-client clean + @$(MAKE) -C owlps-listener clean + @$(MAKE) -C owlps-aggregator clean + @$(MAKE) -C owlps-udp-to-http clean + @$(MAKE) -C owlps-positioning clean purge : - @make -C libowlps purge - @make -C libowlps-client purge - @make -C libowlps-resultreader purge - @make -C owlps-client purge - @make -C owlps-listener purge - @make -C owlps-aggregator purge - @make -C owlps-udp-to-http purge - @make -C owlps-positioning purge + @$(MAKE) -C libowlps purge + @$(MAKE) -C libowlps-client purge + @$(MAKE) -C libowlps-resultreader purge + @$(MAKE) -C owlps-client purge + @$(MAKE) -C owlps-listener purge + @$(MAKE) -C owlps-aggregator purge + @$(MAKE) -C owlps-udp-to-http purge + @$(MAKE) -C owlps-positioning purge ## Help ## From 8bec37c4adcbd53c1a3092b48ee92506d01c9968 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 13:19:46 +0200 Subject: [PATCH 36/46] [Client] Improve the request loop In flood mode, avoid sending a last request when the program is stopped. --- owlps-client/owlps-client.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index fdda899..9fcd21c 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -104,15 +104,11 @@ int main(int argc, char *argv[]) create_socket() ; - request_transmission: - make_packet() ; - send_request() ; - free(packet) ; - - if (options.flood_delay >= 0 && owl_run) + while (owl_run) { - usleep(options.flood_delay * 1000) ; - goto request_transmission ; + send_request() ; + if (options.flood_delay >= 0 && owl_run) + usleep(options.flood_delay * 1000) ; } close(sockfd) ; @@ -379,7 +375,22 @@ void create_socket() -/* Creates the packet to send. */ +/* + * Prepares a new request and sends it. + */ +void send_request() +{ + make_packet() ; + owl_send_request(sockfd, &server, packet, packet_size, + options.nb_pkt, options.delay) ; + free(packet) ; +} + + + +/* + * Creates the packet to send. + */ void make_packet() { uint_fast16_t offset ; // Index used to create the packet @@ -441,14 +452,6 @@ void make_packet() -void send_request() -{ - owl_send_request(sockfd, &server, packet, packet_size, - options.nb_pkt, options.delay) ; -} - - - void receive_position() { // Position of the mobile as computed by the infrastructure: From 40bc6d0b596c9bcdeef27906a6969d7605fa18ee Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 14:05:16 +0200 Subject: [PATCH 37/46] [Listener] Fix reception timestamp struct pcap_pkthdr.ts is host-endian, not net-endian, so we have to convert it to net-endianess when reading it from the packet. --- owlps-listener/owlps-listenerd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index d2f67a6..47037ac 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -926,8 +926,9 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Copy AP MAC : memcpy(request.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ; - // Capture time is in the pcap header (net-endian): - request.start_time = owl_timeval_to_timestamp(header->ts) ; + // Capture time is in the pcap header (host-endian): + request.start_time = + owl_hton_timestamp(owl_timeval_to_timestamp(header->ts)) ; /* Active mode */ if (is_explicit_packet From 98609d146d5f9f5cf6662d7e12f9909c1cd164b6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 15:31:10 +0200 Subject: [PATCH 38/46] [lib] Add owl_msleep() On *BSD, usleep() does not accept an argument greater than 1'000'000 (1 second). owl_msleep() decomposes its arguments to use sleep() and usleep() calls. --- libowlps/libowlps.c | 34 ++++++++++++++++++++++++++++++++++ libowlps/owlps.h | 1 + 2 files changed, 35 insertions(+) diff --git a/libowlps/libowlps.c b/libowlps/libowlps.c index b75f005..3d8bfbf 100644 --- a/libowlps/libowlps.c +++ b/libowlps/libowlps.c @@ -132,6 +132,40 @@ uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel) /* *** Time *** */ +/* + * Sleeps for a given amount of milliseconds. + * 'time_ms' is an unsigned value, so please be careful: passing a + * negative value may not do what you think. + * In case of error, a message is displayed and a non-zero error code + * is returned. + */ +int owl_msleep(uint32_t time_ms) +{ + int ret ; + uint_fast32_t seconds, microseconds ; + + if (! time_ms) + return 0 ; + + seconds = time_ms / 1000 ; + microseconds = time_ms % 1000 * 1000 ; + + if ((ret = sleep(seconds))) + { + perror("Cannot sleep()") ; + return ret ; + } + + if ((ret = usleep(microseconds))) + { + perror("Cannot usleep()") ; + return ret ; + } + + return 0 ; +} + + /* * Sets the owl_timestamp 'now' at the current time. * Returns 0 in case of success non-zero otherwise. diff --git a/libowlps/owlps.h b/libowlps/owlps.h index 7a90c61..78a8f90 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -187,6 +187,7 @@ owl_bool owl_mac_equals(const uint8_t *const mac1, uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel) ; // Time +int owl_msleep(uint32_t time_ms) ; 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) ; From a3c16211c2d04780d86cb3eb27fe8dbadacc1de6 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Wed, 24 Aug 2011 15:41:17 +0200 Subject: [PATCH 39/46] Use owl_msleep() everywhere --- libowlps-client/libowlps-client.c | 2 +- owlps-aggregator/owlps-aggregatord.c | 4 ++-- owlps-client/owlps-client.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libowlps-client/libowlps-client.c b/libowlps-client/libowlps-client.c index ff44774..669c12d 100644 --- a/libowlps-client/libowlps-client.c +++ b/libowlps-client/libowlps-client.c @@ -88,7 +88,7 @@ void owl_send_request(const int sockfd, // Transmit remaining packets (if any): for (i = 0 ; i < nb_pkt - 1 ; ++i) { - usleep(delay * 1000) ; // Wait during the wanted delay + owl_msleep(delay) ; // Wait during the wanted delay owl_send_packet(sockfd, server, packet, packet_size) ; } diff --git a/owlps-aggregator/owlps-aggregatord.c b/owlps-aggregator/owlps-aggregatord.c index 557a931..21cb4b4 100644 --- a/owlps-aggregator/owlps-aggregatord.c +++ b/owlps-aggregator/owlps-aggregatord.c @@ -711,7 +711,7 @@ void* monitor_requests(void *NULL_value) fflush(NULL) ; // Wait to check again: - usleep(cfg_getint(cfg, "check_interval") * 1000) ; + owl_msleep(cfg_getint(cfg, "check_interval")) ; } /* Close output file & socket */ @@ -1077,7 +1077,7 @@ void* monitor_aps(void *NULL_value) } sem_post(&lock_aps) ; - usleep(cfg_getint(cfg, "ap_check_interval") * 1000) ; + owl_msleep(cfg_getint(cfg, "ap_check_interval")) ; } pthread_exit(NULL_value) ; diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 9fcd21c..cd55368 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) { send_request() ; if (options.flood_delay >= 0 && owl_run) - usleep(options.flood_delay * 1000) ; + owl_msleep(options.flood_delay) ; } close(sockfd) ; From 7432716a3c4d437d1573c923ef564d5e5ad2d463 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 10:25:40 +0200 Subject: [PATCH 40/46] [UDP-HTTP] Fix memory leak in free_result_list() --- owlps-udp-to-http/owlps-udp-to-http.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index c83125d..86ef279 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -496,14 +496,13 @@ void realloc_answer(size_t new_size) */ void free_results_list() { + results_list *tmp_res ; while (results != NULL) { owl_free_result(results->result) ; + tmp_res = results ; results = results->next ; -#ifndef NDEBUG - --nb_results ; -#endif // NDEBUG + free(tmp_res) ; } - assert(nb_results == 0) ; nb_results = 0 ; } From 3fec57b1ae2428308ef9f0ffaad6e750315a7470 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 11:09:41 +0200 Subject: [PATCH 41/46] Move all error #defines in owlps.h --- libowlps-client/libowlps-client.c | 4 ++-- libowlps-client/owlps-client.h | 4 ---- libowlps/owlps.h | 25 ++++++++++++++++++++++++- owlps-aggregator/owlps-aggregator.h | 9 --------- owlps-aggregator/owlps-aggregatord.c | 22 +++++++++++----------- owlps-client/owlps-client.c | 11 ++++------- owlps-listener/owlps-listener.h | 9 --------- owlps-listener/owlps-listenerd.c | 24 ++++++++++++------------ 8 files changed, 53 insertions(+), 55 deletions(-) diff --git a/libowlps-client/libowlps-client.c b/libowlps-client/libowlps-client.c index 669c12d..2e68518 100644 --- a/libowlps-client/libowlps-client.c +++ b/libowlps-client/libowlps-client.c @@ -29,7 +29,7 @@ int owl_create_trx_socket(const char *const dest_ip, { perror("Error! Cannot create UDP sending socket to the aggregation" " server") ; - exit(ERR_CREATING_SOCKET) ; + exit(OWL_ERR_SOCKET_CREATE) ; } // If we specified an interface name @@ -110,7 +110,7 @@ void owl_send_packet(const int sockfd, if (nsent != (ssize_t) packet_size) { perror("Error sending data to the aggregation server") ; - exit(ERR_SENDING_INFO) ; + exit(OWL_ERR_SOCKET_SEND) ; } #ifdef DEBUG diff --git a/libowlps-client/owlps-client.h b/libowlps-client/owlps-client.h index 8a206cd..cb464d6 100644 --- a/libowlps-client/owlps-client.h +++ b/libowlps-client/owlps-client.h @@ -8,10 +8,6 @@ #include -/* Error codes */ -#define ERR_CREATING_SOCKET 151 // Error when creating output socket -#define ERR_SENDING_INFO 152 // Error sending a localisation request - /* Function headers */ int owl_create_trx_socket(const char *const dest_ip, diff --git a/libowlps/owlps.h b/libowlps/owlps.h index 78a8f90..fe918b4 100644 --- a/libowlps/owlps.h +++ b/libowlps/owlps.h @@ -173,8 +173,31 @@ typedef struct _owl_autocalibration_order extern owl_bool owl_run ; -/* Function error codes */ +/* Error codes */ +/* User interface */ +// Wrong program invokation (command-line arguments): +#define OWL_ERR_BAD_USAGE 100 +// Error when reading/parsing the configuration file: +#define OWL_ERR_CONFIG_FILE 101 +/* System */ +// Error when creating a thread: +#define OWL_ERR_THREAD_CREATE 110 +// Wrong signal received: #define OWL_ERR_BAD_SIGNAL 111 +/* Network communication */ +// Error when creating a socket: +#define OWL_ERR_SOCKET_CREATE 120 +// Error when sending a message on a socket: +#define OWL_ERR_SOCKET_SEND 121 +// Error when reading from a socket: +#define OWL_ERR_SOCKET_RECV 122 +/* Network interface / capture */ +// Error when opening the capture interface: +#define OWL_ERR_IFACE_PCAP_OPEN 130 +// Error when reading the interface Wi-Fi mode: +#define OWL_ERR_IFACE_MODE_GET 131 +// Error when setting the interface Wi-Fi mode: +#define OWL_ERR_IFACE_MODE_SET 132 /* Function headers */ diff --git a/owlps-aggregator/owlps-aggregator.h b/owlps-aggregator/owlps-aggregator.h index bf07eaf..97a129d 100644 --- a/owlps-aggregator/owlps-aggregator.h +++ b/owlps-aggregator/owlps-aggregator.h @@ -27,15 +27,6 @@ #define VERBOSE_REQUESTS cfg_getint(cfg, "verbose") >= 4 -/* Error codes */ -#define ERR_NO_MESSAGE_RECEIVED 1 // Error when reading the socket -#define ERR_CREATING_SOCKET 2 // Erreur when creating listening socket -#define ERR_BAD_USAGE 3 // Bad program call -#define ERR_PARSING_CONFIG_FILE 4 // Error reading the configuration file -#define ERR_SENDING_INFO 5 // Error sending a message on a socket -#define ERR_CREATING_THREAD 6 // Error creating a thread - - /* Linked list storing data of each request */ typedef struct _request_info_list { diff --git a/owlps-aggregator/owlps-aggregatord.c b/owlps-aggregator/owlps-aggregatord.c index 21cb4b4..ecc3db7 100644 --- a/owlps-aggregator/owlps-aggregatord.c +++ b/owlps-aggregator/owlps-aggregatord.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) fprintf(stderr, "Error! Cannot listen on port %"PRIuFAST16".\n", listening_port) ; - ret = ERR_CREATING_SOCKET ; + ret = OWL_ERR_SOCKET_CREATE ; goto exit ; } @@ -79,7 +79,7 @@ int main(int argc, char **argv) if (ret != 0) { perror("Cannot create monitor thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } if (cfg_getbool(cfg, "autocalibration")) @@ -89,7 +89,7 @@ int main(int argc, char **argv) if (ret != 0) { perror("Cannot create autocalibration hello thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } ret = pthread_create(&monitor_aps_thread, NULL, @@ -97,7 +97,7 @@ int main(int argc, char **argv) if (ret != 0) { perror("Cannot create monitor APs thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } } @@ -276,7 +276,7 @@ int parse_config_file(int argc, char **argv) config_file) ; free(config_file) ; owl_run = owl_false ; - return ERR_PARSING_CONFIG_FILE ; + return OWL_ERR_CONFIG_FILE ; } free(config_file) ; @@ -342,7 +342,7 @@ int parse_command_line(int argc, char **argv) default : print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } } @@ -358,7 +358,7 @@ int check_configuration() fprintf(stderr, "Error! You must specify an output file.\n") ; print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } // listening_port // @@ -388,7 +388,7 @@ int check_configuration() " localisation server.\n") ; print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } // aggregate_timeout // @@ -467,7 +467,7 @@ int read_loop(int sockfd) if (owl_run) { perror("No request received from listener") ; - ret = ERR_NO_MESSAGE_RECEIVED ; + ret = OWL_ERR_SOCKET_RECV ; } break ; } @@ -904,7 +904,7 @@ void* listen_for_aps(void *NULL_value) { perror("Error! Cannot create UDP listening socket from the" " listeners") ; - exit(ERR_CREATING_SOCKET) ; + exit(OWL_ERR_SOCKET_CREATE) ; } pthread_cleanup_push(&owl_close_fd, &listen_sockfd) ; @@ -1178,7 +1178,7 @@ void order_send(ap_list *ap) if (nsent != (ssize_t) sizeof(message)) { perror("Error sending order to the listener") ; - exit(ERR_SENDING_INFO) ; + exit(OWL_ERR_SOCKET_SEND) ; } close(sockfd) ; diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index cd55368..794bb10 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -14,9 +14,6 @@ #include -/* Error codes */ -#define ERR_BAD_USAGE 1 // Bad program call (bad number of arguments) - /* Number of packets to send */ #define DEFAULT_NBPKT_CALIB 20 // 20 packets when calibrating #define DEFAULT_NBPKT_NORMAL 10 // 10 packets when requesting the position @@ -210,7 +207,7 @@ void parse_main_options(int argc, char **argv) exit(0) ; default : print_usage() ; - exit(ERR_BAD_USAGE) ; + exit(OWL_ERR_BAD_USAGE) ; } } } @@ -225,7 +222,7 @@ void check_destination_ip() fprintf(stderr, "Error! You must specify a destination IP address" " (-d).\n") ; print_usage() ; - exit(ERR_BAD_USAGE) ; + exit(OWL_ERR_BAD_USAGE) ; } } @@ -247,7 +244,7 @@ void parse_calibration_data(int argc, char **argv) else // Bad number of arguments { print_usage() ; - exit(ERR_BAD_USAGE) ; + exit(OWL_ERR_BAD_USAGE) ; } } } @@ -289,7 +286,7 @@ void check_configuration() { fprintf(stderr, "Error! « %"PRIu8" » is not a valid" " direction.\n", options.direction) ; - exit(ERR_BAD_USAGE) ; + exit(OWL_ERR_BAD_USAGE) ; } // Check port numbers diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index e9a9bbd..b52a48f 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -154,15 +154,6 @@ enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ; //#define RTAP_EXT 31 -/* Error codes */ -#define ERR_OPENING_IFACE 2 // Error when opening capture interface -#define ERR_BAD_USAGE 3 // Bad program call -#define ERR_PARSING_CONFIG_FILE 4 // Error reading the configuration file -#define ERR_CREATING_THREAD 6 // Error creating a thread -#define ERR_SETTING_MODE 101 -#define ERR_READING_MODE 104 - - /* Function headers */ int initialise_configuration(int argc, char **argv) ; int parse_config_file(int argc, char **argv) ; diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 47037ac..7cc7aeb 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) if (ret != 0) { perror("Cannot create keep monitor thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } } @@ -164,7 +164,7 @@ int main(int argc, char *argv[]) if (ret != 0) { perror("Cannot create autocalibration thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) if (ret != 0) { perror("Cannot create autocalibration hello thread") ; - ret = ERR_CREATING_THREAD ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } } @@ -397,7 +397,7 @@ int parse_config_file(int argc, char **argv) config_file) ; free(config_file) ; owl_run = owl_false ; - return ERR_PARSING_CONFIG_FILE ; + return OWL_ERR_CONFIG_FILE ; } free(config_file) ; #endif // USE_CONFIG_FILE @@ -522,7 +522,7 @@ int parse_main_options(int argc, char **argv) default : print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } } @@ -549,7 +549,7 @@ int parse_calibration_data(int argc, char **argv) { print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } } @@ -571,7 +571,7 @@ int check_configuration() fprintf(stderr, "Error! Unknown mode « %c ».\n", (char) GET_MODE()) ; print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } if (GET_RTAP_IFACE()[0] == '\0') @@ -580,7 +580,7 @@ int check_configuration() " for the capture.\n") ; print_usage() ; owl_run = owl_false ; - return ERR_BAD_USAGE ; + return OWL_ERR_BAD_USAGE ; } if (GET_WIFI_IFACE()[0] == '\0') @@ -749,7 +749,7 @@ int iface_mode_monitor(const char *const iface) if (ioctl(sockfd, SIOCGIWMODE, &wrq) == -1) // Get current mode { perror("Error reading interface mode") ; - return ERR_READING_MODE ; + return OWL_ERR_IFACE_MODE_GET ; } // If interface is not yet in Monitor mode @@ -759,7 +759,7 @@ int iface_mode_monitor(const char *const iface) if (ioctl(sockfd, SIOCSIWMODE, &wrq) == -1) // Set up Monitor mode { perror("Error setting up Monitor mode") ; - return ERR_SETTING_MODE ; + return OWL_ERR_IFACE_MODE_SET ; } } @@ -785,7 +785,7 @@ int capture() if (capture_handler == NULL) // Capture starting failed { fprintf(stderr, "Cannot open capture interface %s\n", errbuf) ; - return ERR_OPENING_IFACE ; + return OWL_ERR_IFACE_PCAP_OPEN ; } /* Open UDP socket to the aggregator */ @@ -1302,7 +1302,7 @@ void* autocalibrate(void *NULL_value) { perror("Error! Cannot create UDP listening socket from the" " aggregation server") ; - exit(ERR_CREATING_SOCKET) ; + exit(OWL_ERR_SOCKET_CREATE) ; } pthread_cleanup_push(&owl_close_fd, &listen_sockfd) ; From c52321a52b378ed35b880341d021f40073df09e8 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 11:27:37 +0200 Subject: [PATCH 42/46] [UDP-HTTP] Use error codes from owlps.h --- owlps-udp-to-http/owlps-udp-to-http.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 86ef279..1b24d73 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -110,7 +110,7 @@ int main(int argc, char *argv[]) if (ret) { perror("Cannot create the TCP server thread") ; - ret = 1 ; + ret = OWL_ERR_THREAD_CREATE ; goto exit ; } @@ -156,14 +156,14 @@ int receive_udp() /* Open the UDP socket */ udp_sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; if (udp_sockfd < 0) - return 1 ; + return OWL_ERR_SOCKET_CREATE ; /* UDP read loop */ while (owl_run) { result = owl_receive_position(udp_sockfd) ; if (result == NULL) - return 1 ; + return OWL_ERR_SOCKET_RECV ; owl_print_result(result) ; store_result(result) ; printf("--------------\n") ; @@ -232,7 +232,7 @@ int init_tcp_socket() if (tcp_sockfd < 0) { perror("Error opening the TCP socket") ; - return tcp_sockfd ; + return OWL_ERR_SOCKET_CREATE ; } bzero((char *) &server_addr, sizeof(server_addr)) ; @@ -245,7 +245,7 @@ int init_tcp_socket() sizeof(server_addr)) < 0) { perror("Error binding the TCP socket") ; - return -1 ; + return OWL_ERR_SOCKET_CREATE ; } return 0 ; @@ -319,6 +319,10 @@ void* tcp_server(void *NULL_value) } +/* + * Reads a message and search for a request in it. + * Returns the identifier of a request if found, or 0 if not found. + */ int extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], char *client_message) From 31bea165c5981f254a1a46aac7fb3af4b5d14140 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 11:29:44 +0200 Subject: [PATCH 43/46] [lib] create*socket(): return standard error code --- libowlps/libowlps.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libowlps/libowlps.c b/libowlps/libowlps.c index 3d8bfbf..d2300a5 100644 --- a/libowlps/libowlps.c +++ b/libowlps/libowlps.c @@ -137,7 +137,7 @@ uint_fast8_t owl_frequency_to_channel(const uint_fast16_t channel) * 'time_ms' is an unsigned value, so please be careful: passing a * negative value may not do what you think. * In case of error, a message is displayed and a non-zero error code - * is returned. + * is returned (if positive, it is the number of non-sleeped seconds). */ int owl_msleep(uint32_t time_ms) { @@ -331,6 +331,7 @@ float owl_swap_float(const float f) * description will be saved. * - client_description (in/out): the structure in which the client * description will be saved. + * Returns a negative error code in case of error. */ int owl_create_udp_trx_socket(const char *const server_address, const uint_fast16_t server_port, @@ -344,7 +345,7 @@ int owl_create_udp_trx_socket(const char *const server_address, if (sockfd < 0) { perror("UDP socket creation failed") ; - return sockfd ; + return -OWL_ERR_SOCKET_CREATE ; } /* Initialise the client structure */ @@ -368,6 +369,7 @@ int owl_create_udp_trx_socket(const char *const server_address, * Creates a UDP reception socket and returns its descriptor. * Parameters: * - port: port on which the socket listens. + * Returns a negative error code in case of error. */ int owl_create_udp_listening_socket(const uint_fast16_t port) { @@ -380,7 +382,7 @@ int owl_create_udp_listening_socket(const uint_fast16_t port) if (sockfd < 0) { perror("UDP socket creation failed") ; - return sockfd ; + return -OWL_ERR_SOCKET_CREATE ; } /* Initialise the server structure */ @@ -397,7 +399,7 @@ int owl_create_udp_listening_socket(const uint_fast16_t port) { perror("Cannot bind the UDP socket") ; close(sockfd) ; - return ret ; + return -OWL_ERR_SOCKET_CREATE ; } return sockfd ; From b22a42a524214ec8cc1f397c833efdad73793f7b Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 15:54:46 +0200 Subject: [PATCH 44/46] [Client] Fix the request loop 8bec37c4 caused the non-flood mode to flood. --- owlps-client/owlps-client.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 794bb10..2103a8b 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -101,11 +101,12 @@ int main(int argc, char *argv[]) create_socket() ; - while (owl_run) + send_request() ; + while (owl_run && options.flood_delay >= 0) { - send_request() ; - if (options.flood_delay >= 0 && owl_run) - owl_msleep(options.flood_delay) ; + owl_msleep(options.flood_delay) ; + if (owl_run) // owl_run can have been set to false during the sleep + send_request() ; } close(sockfd) ; From 91609a40fe7f23521627b71cd231e7cb6849627a Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 16:00:22 +0200 Subject: [PATCH 45/46] [Client] Use libowlps-resultreader Use functions from libowlps-resultreader in receive_position(). By the way, this function is still not really useful, as we do not verify that the received result correspond to the set request. --- owlps-client/Makefile | 7 +++++-- owlps-client/owlps-client.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/owlps-client/Makefile b/owlps-client/Makefile index a81b1da..859a08d 100644 --- a/owlps-client/Makefile +++ b/owlps-client/Makefile @@ -27,8 +27,10 @@ HEADER= # Flags LIBOWLPS_DIR = ../libowlps LIBOWLPSCLIENT_DIR = ../libowlps-client +LIBOWLPSRESULTREADER_DIR = ../libowlps-resultreader CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes \ - -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) + -I$(LIBOWLPS_DIR) -I$(LIBOWLPSCLIENT_DIR) \ + -I$(LIBOWLPSRESULTREADER_DIR) #CFLAGS += -g -O0 DEPFLAGS = -MMD XCFLAGS = $(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) @@ -36,7 +38,8 @@ PICFLAG = -fPIC OWLPSFLAGS = -D OWLPS_VERSION=\"$(OWLPS_VERSION)\" OWLPSFLAGS += -D DEBUG LIBS = -L$(LIBOWLPS_DIR) -lowlps \ - -L$(LIBOWLPSCLIENT_DIR) -lowlps-client + -L$(LIBOWLPSCLIENT_DIR) -lowlps-client \ + -L$(LIBOWLPSRESULTREADER_DIR) -lowlps-resultreader OS := $(shell uname) ifeq ("$(OS)", "Linux") diff --git a/owlps-client/owlps-client.c b/owlps-client/owlps-client.c index 2103a8b..e3a5718 100644 --- a/owlps-client/owlps-client.c +++ b/owlps-client/owlps-client.c @@ -3,6 +3,7 @@ */ #include +#include #include #include @@ -41,7 +42,7 @@ void print_configuration(void) ; void create_socket(void) ; void make_packet(void) ; void send_request(void) ; -void receive_position(void) ; +int receive_position(void) ; void print_usage(void) ; void print_version(void) ; @@ -87,6 +88,7 @@ uint_fast16_t packet_size ; // Packet size int main(int argc, char *argv[]) { struct sigaction action ; // Signal handler structure + int ret = 0 ; program_name = argv[0] ; parse_command_line(argc, argv) ; @@ -112,9 +114,9 @@ int main(int argc, char *argv[]) close(sockfd) ; if (options.listening_port > 0) - receive_position() ; + ret = receive_position() ; - return 0 ; + return ret ; } @@ -450,18 +452,31 @@ void make_packet() -void receive_position() +/* + * Receives a position computed by the infrastructure. + * Note that it is currently not guaranteed that the received result + * correspond to the request sent. + * Returns 0, or a non-zero value in case of error. + */ +int receive_position() { - // Position of the mobile as computed by the infrastructure: - float x, y, z ; + owl_result *result ; + + printf("Waiting for the result from the infrastructure...\n") ; sockfd = owl_create_udp_listening_socket(options.listening_port) ; - recvfrom(sockfd, &x, sizeof(float), 0, NULL, NULL) ; - recvfrom(sockfd, &y, sizeof(float), 0, NULL, NULL) ; - recvfrom(sockfd, &z, sizeof(float), 0, NULL, NULL) ; - close(sockfd) ; + if (sockfd < 0) + return OWL_ERR_SOCKET_CREATE ; - printf("Computed position: (%.4f;%.4f;%.4f)\n", x, y, z) ; + result = owl_receive_position(sockfd) ; + if (result == NULL) + return OWL_ERR_SOCKET_RECV ; + + close(sockfd) ; + owl_print_result(result) ; + owl_free_result(result) ; + + return 0 ; } From 33167601bfc473c811d3d7ceb6576a561e837cea Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 26 Aug 2011 16:08:39 +0200 Subject: [PATCH 46/46] Update TODO --- TODO | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 7fd9f0a..6ab278c 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,21 @@ * Global +- Known bugs + ° libconfuse bugs (Listener & Aggregator): + . http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639074 + . http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=639115 +- Rename some fields in the structures + ° start_time -> rx_time, first_rx_time +- Eliminate remaining exit() calls to avoid memory leaks on exit. - Add option dump-configuration (displays the config & exits). - Makefiles: ° Translate comments & help. ° Merge Makefile and Makefile_atheros*. Use template makefiles, autohell, cmake…? -- Use string for network exchanges? +- Use a string for positioning requests + Instead of a binary packet, use a CSV string containing the request + information. This will allow easy developments of clients in other + languages. - Mark arguments as const in function headers if needed Mostly done in the owlps-positioning C++ code (should check that), but not constantly in C modules. @@ -52,9 +62,17 @@ Get rid of the "Cannot open configuration file" error, in quiet mode and when the default configuration file has to be used (no file specified by the user with -f). -- Listen for autocalibration requests without sending requests? +- Filter the number of implicit packets per mobile? + Currently, in passive or mixed mode, *all* the receive packets are + transmitted to the aggregator. +- Option "read-only autocalibration"? + 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. +- BSD port + http://www.unixgarden.com/index.php/programmation/introduction-a-la-programmation-wifi-en-c-sous-netbsd +- Use the "official" radiotap parser? (Expat license) + http://git.sipsolutions.net/?p=radiotap.git * Client @@ -65,16 +83,35 @@ Could be nice, but probably useless. +* UDP to HTTP + +- Command-line options (port numbers, -v/-q, -h, -V). +- Delete inactive clients after a given amount of time. +- Refactor prepare_answer(). + + * Positioning - Known bugs ° Cannot compute the error (Real) with autocalibration requests. - Algorithms + ° Add to the result the information "area error" (whether on not the + computed result is in the same room as the real position). + ° Delete reference points after a given amount of time. This is to + avoid meaningless old reference points, for instance if an AP was + shut down. + ° Handle the power and antenna gain difference between the + calibration mobile (or pseudo-mobile, for autocalibration) and the + mobile to position. ° MinMax: use a different step for X, Y and Z? - Autocalibration ° Generate reference points in 3D. + ° Check what happens with >4 APs, and fix it. We certainly should + select APs not only by the angle proximity, but also by the + distance proximity. Maybe implement three options: angle, distance, + and angle + distance. ° Handle 2 APs, not only >2 APs. ° Find why some CalibrationRequest were not deleted when calling Stock::delete_calibration_request() (via @@ -108,7 +145,12 @@ with relative path in owlps-positioning.cfg in the same directory). - Optimisation & code improvement - ° Multithread algorithm calls. + ° Multithreading: + . algorithm (parallelize computation of the different algorithms + for the same request) ; + . and/or requests (parallelize computation of several requests). + It would be possible (overkill?) to have a group of worker threads + and a job queue. ° ReferencePoint: the request list should be an unordered_set instead of a vector, to guarantee the unicity of the elements. ° Pre-allocate vectors' memory with reserve().