[Positioning] Directory reorganization

Move "new" source files in src/.
Update Doxyfile and Makefile.

Delete old useless files:
- libowlps-positioning.*
- positioning.*
- server.*
- treatment.*
This commit is contained in:
Matteo Cypriani 2010-02-26 16:03:14 +01:00
parent 7264080536
commit c559b827ee
57 changed files with 84 additions and 1857 deletions

View File

@ -568,7 +568,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT =
INPUT = src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -597,7 +597,7 @@ RECURSIVE = NO
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = libowlps-positioning.hh libowlps-positioning.cc owlps-positioning.hh owlps-positioning.cc positioning.hh positioning.cc server.hh server.cc treatment.hh treatment.cc
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded

View File

@ -1,5 +1,7 @@
.PHONY : all test doc clean purge install uninstall style check
.PHONY : all test doc prepare clean purge install uninstall style check
SRC_DIR = src
OBJ_DIR = obj
TESTS_DIR = tests
DOXYGEN_DIR = doc
DOXYFILE = Doxyfile
@ -11,7 +13,9 @@ INSTALL_DIR = $(PREFIX)/bin
# System tools
RM = rm -fv
RM_RECURSIVE = \rm -fr
RM_RECURSIVE_VERBOSE = rm -frv
CP = cp -v
MKDIR = mkdir -pv
# Other tools
STYLE = astyle --style=gnu --formatted
@ -21,14 +25,18 @@ DOXYGEN = doxygen
# Compilation tools and flags
GXX = g++-4.4
#DEBUG = -g
TESTSGXXFLAGS = -I$(TESTS_DIR) -I.
TESTSGXXFLAGS = -I$(TESTS_DIR) -I$(SRC_DIR) -I.
GXXFLAGS = $(DEBUG) -Wall -Wextra
LD = $(GXX)
LDFLAGS = -lm -lrt -lboost_program_options
# Targets
TARGET = owlps-positioning
OBJ = posutil.o \
OBJ_TARGET = $(OBJ_DIR)/$(TARGET).o
SOURCE_TARGET = $(SRC_DIR)/$(TARGET).cc
OBJ_LIST = \
posutil.o \
stock.o \
timestamp.o \
direction.o \
@ -48,54 +56,91 @@ OBJ = posutil.o \
input.o \
inputcsv.o \
inputlogcsv.o
OBJ_NOTEST = posexcept.o \
inputmedium.o
INTERFACES = inputlogmedium.hh
OBJ_NOTEST_LIST = \
posexcept.o \
inputmedium.o
INTERFACES_LIST = inputlogmedium.hh
OBJ = $(OBJ_LIST:%=$(OBJ_DIR)/%)
OBJ_NOTEST = $(OBJ_NOTEST_LIST:%=$(OBJ_DIR)/%)
INTERFACES = $(INTERFACES_LIST:%=$(SRC_DIR)/%)
SOURCE = \
$(OBJ:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.hh) \
$(OBJ:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.cc) \
$(OBJ_NOTEST:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.hh) \
$(OBJ_NOTEST:$(OBJ_DIR)/%.o=$(SRC_DIR)/%.cc) \
$(INTERFACES)
TESTS_XX = $(TESTS_DIR)/tests.cc
TESTS_OBJ = $(TESTS_DIR)/tests.o
TESTS_TARGET = $(TESTS_DIR)/tests
TESTUTIL_OBJ = $(TESTS_DIR)/testutil.o
TESTSETUP_OBJ = $(TESTS_DIR)/testsetup.o
SOURCE_TESTS = $(OBJ:%.o=$(TESTS_DIR)/%_test.hh)
SOURCE_TESTS = $(OBJ:$(OBJ_DIR)/%.o=$(TESTS_DIR)/%_test.hh)
OBJ_TESTS = $(TESTUTIL_OBJ) $(TESTSETUP_OBJ)
INCLUDES_TESTS = $(TESTS_DIR)/valuetraits.hh
all: $(TARGET)
all: prepare $(TARGET)
# Generic targets
$(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cc $(TESTS_DIR)/%.hh
$(GXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
%.o: %.cc %.hh
$(GXX) $(GXXFLAGS) -c $<
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh
$(GXX) $(GXXFLAGS) -o $@ -c $<
%: %.o
%: $(OBJ_DIR)/%.o
$(LD) $(LDFLAGS) -o $@ $^
# Dependencies
userinterface.o: configuration.o
referencepoint.o: point3d.o
waypoint.o: point3d.o building.o
area.o: building.o point3d.o
wifidevice.o: posutil.o
accesspoint.o: wifidevice.o point3d.o
mobile.o: wifidevice.o
measurement.o: accesspoint.o
request.o: timestamp.o measurement.o
calibrationrequest.o: request.o referencepoint.o direction.o
inputcsv.o: inputmedium.o request.o calibrationrequest.o stock.o
inputlogcsv.o: inputlogmedium.hh request.o
input.o: posexcept.o
userinterface.o: \
$(OBJ_DIR)/configuration.o
referencepoint.o: \
$(OBJ_DIR)/point3d.o
waypoint.o: \
$(OBJ_DIR)/point3d.o \
$(OBJ_DIR)/building.o
area.o: \
$(OBJ_DIR)/building.o \
$(OBJ_DIR)/point3d.o
wifidevice.o: \
$(OBJ_DIR)/posutil.o
accesspoint.o: \
$(OBJ_DIR)/wifidevice.o \
$(OBJ_DIR)/point3d.o
mobile.o: \
$(OBJ_DIR)/wifidevice.o
measurement.o: \
$(OBJ_DIR)/accesspoint.o
request.o: \
$(OBJ_DIR)/timestamp.o \
$(OBJ_DIR)/measurement.o
calibrationrequest.o: \
$(OBJ_DIR)/request.o \
$(OBJ_DIR)/referencepoint.o \
$(OBJ_DIR)/direction.o
inputcsv.o: \
$(OBJ_DIR)/inputmedium.o \
$(OBJ_DIR)/request.o \
$(OBJ_DIR)/calibrationrequest.o \
$(OBJ_DIR)/stock.o
inputlogcsv.o: \
$(OBJ_DIR)/inputlogmedium.hh \
$(OBJ_DIR)/request.o
input.o: \
$(OBJ_DIR)/posexcept.o
# Specific targets
$(TARGET): $(OBJ) $(OBJ_NOTEST)
$(TARGET): $(OBJ) $(OBJ_NOTEST) $(OBJ_TARGET)
$(TESTS_XX): $(SOURCE_TESTS)
$(OBJ_TARGET): $(SOURCE_TARGET)
$(GXX) $(GXXFLAGS) -o $@ -c $<
$(TESTS_XX): $(SOURCE_TESTS) $(OBJ)
$(TESTS_DIR)/cxxtestgen.pl --error-printer \
--include=$(TESTS_DIR)/valuetraits.hh \
--include=$(TESTUTIL_OBJ:.o=.hh) \
-o $@ $^
-o $@ $(SOURCE_TESTS)
$(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
$(GXX) $(GXXFLAGS) $(TESTSGXXFLAGS) -o $@ -c $<
@ -103,16 +148,19 @@ $(TESTS_OBJ): $(TESTS_XX) $(INCLUDES_TESTS)
$(TESTS_TARGET): $(TESTS_OBJ) $(OBJ_TESTS) $(OBJ) $(OBJ_NOTEST)
$(LD) $(LDFLAGS) -o $@ $^
test: $(TESTS_TARGET)
test: prepare $(TESTS_TARGET)
@$(TESTS_TARGET)
doc:
@$(DOXYGEN) $(DOXYFILE)
prepare:
@$(MKDIR) $(OBJ_DIR)
clean:
@$(RM) *~ *.o *.gch *.orig
@$(RM) $(TESTS_XX) $(TESTS_DIR)/*~ $(TESTS_DIR)/*.o \
$(TESTS_DIR)/*.orig
@$(RM) *~ */*~ *.orig */*.orig
@$(RM_RECURSIVE_VERBOSE) $(OBJ_DIR)
@$(RM) $(TESTS_XX) $(TESTS_DIR)/*.o
purge: clean
@$(RM) $(TARGET)
@ -129,16 +177,11 @@ uninstall:
style:
@$(STYLE) \
$(OBJ:.o=.hh) \
$(OBJ:.o=.cc) \
$(OBJ_NOTEST:.o=.hh) \
$(OBJ_NOTEST:.o=.cc) \
$(INTERFACES) \
$(SOURCE) \
$(TESTS_DIR)/*.hh \
$(TESTS_DIR)/*.cc
check:
@$(CPPCHECK) \
$(OBJ:.o=.hh) $(OBJ:.o=.cc) \
$(OBJ_NOTEST:.o=.hh) $(OBJ_NOTEST:.o=.cc) \
$(INTERFACES) $(TARGET).cc
$(SOURCE) \
$(TARGET).cc

View File

@ -5,13 +5,6 @@
- PosUtil
° Déplacer les #define des canaux Wi-Fi dans le .cc
- Réorganisation du dépôt ?
owlps-positioning/src
owlps-positioning/include
owlps-positioning/tests/src
owlps-positioning/tests/include
owlps-positioning/doc (générée par doxygen)
- Revoir le diagramme UML
° Associations : devraient êtres représentées par des attributs
pointeurs.

View File

@ -1,110 +0,0 @@
#include "libowlps-positioning.hh"
/* Tronque le float "f" à "n" décimales et le retourne */
float round_float(float f, int n)
{
n = (int) pow((double) 10, (double) n) ;
float f_dec = modff(f, &f) ;
f_dec = floor(f_dec * n) / n ;
return f + f_dec ;
}
/* Explodes a string into substrings based on separator sep. Returns a string vector. */
vector<string> explode(const string &input, const char &sep)
{
vector<string> vs;
string tmp;
unsigned int i;
for (i = 0 ; i < input.size() ; i++)
if (input[i] == sep)
{
vs.push_back(tmp);
tmp.clear();
}
else
{
tmp.push_back(input[i]);
}
vs.push_back(tmp);
tmp.clear();
return vs;
}
/* Le Format Fred n'est pas utilisé */
vector<string> extractReferencePointInfoFromBuffer(const string &buffer_in)
{
unsigned int i = 0;
string tmp_field;
vector<string> ret;
/* Extract coordinates */
/* x */
while (buffer_in[i] != ';')
{
tmp_field.push_back(buffer_in[i]);
i++;
}
ret.push_back(tmp_field);
tmp_field.clear();
i++; // go after the ';'
/* y */
while (buffer_in[i] != ';')
{
tmp_field.push_back(buffer_in[i]);
i++;
}
ret.push_back(tmp_field);
tmp_field.clear();
i++;
/* z */
while (buffer_in[i] != ';')
{
tmp_field.push_back(buffer_in[i]);
i++;
}
ret.push_back(tmp_field);
tmp_field.clear();
i++;
/* Extract direction (not used now) */
while (buffer_in[i] != ';')
{
tmp_field.push_back(buffer_in[i]);
i++;
}
ret.push_back(tmp_field);
tmp_field.clear();
i++;
while (i <= buffer_in.size())
{
if ((buffer_in[i] == ';' || i == buffer_in.size()) && !tmp_field.empty()) // Si on est sur un séparateur et que la valeur lue n'est pas vide,
{
ret.push_back(tmp_field) ; // on met la valeur lue dans les valeurs de retour.
tmp_field.clear() ;
}
else // Si on n'est pas sur un séparateur,
tmp_field.push_back(buffer_in[i]) ; // on ajoute le caractère courant à la suite de la valeur lue.
i++ ;
}
/* Return the vector with each data */
return ret;
}
uint64_t timeval_to_ms(const struct timeval &d)
{
return d.tv_sec * 1000 + d.tv_usec / 1000 ;
}

View File

@ -1,65 +0,0 @@
#ifndef _LIBOWLPS_POSITINING_HH_
#define _LIBOWLPS_POSITINING_HH_
#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <stdint.h>
#include <map>
#include <set>
#include <vector>
#include <ctime>
#include <sys/time.h>
#include <postgresql/libpq-fe.h>
#define DEFAULT_AP_FILE "csv/minipc.cfg"
#define DEFAULT_PT_FILE "csv/toutes.csv"
#define DEFAULT_TOPO_FILE "csv/topo.csv"
#define DEFAULT_WAYPOINT_FILE "csv/waypoints.csv"
#define DEFAULT_CONFIG_FILE "owlps-positioning.cfg"
#define DEFAULT_BDD_HOST "127.0.0.1"
#define DEFAULT_BDD_NAME "owlps_db"
#define DEFAULT_BDD_USER "owlps"
#define DEFAULT_BDD_PASS "owlps"
#define LIGHT_SPEED 300000000
#define MINMAX_STEP 0.5
#define MINMAX_X_START 0.5
#define MINMAX_Y_START 0.5
#define MINMAX_Z_START 0
#define MINMAX_X_STOP 10
#define MINMAX_Y_STOP 31.5
#define MINMAX_Z_STOP 6
typedef struct _couple_info
{
unsigned char ap_mac_addr_bytes[6]; // Adresse MAC de l'AP
int antenna_signal_dbm; // Puissance du signal reçu par l'AP
} couple_info;
typedef struct _request
{
unsigned char mobile_mac_addr_bytes[6]; //Adresse MAC du mobile
struct timeval request_time; // Date sur le client
int nb_couples; // Nombre couples (MAC AP;Puissance)
} request;
//using namespace std ;
float round_float(float f, int n);
vector<string> explode(const string &input, const char &sep);
vector<string> extractReferencePointInfoFromBuffer(const string &buffer_in);
uint64_t timeval_to_ms(const struct timeval &d);
#endif

View File

@ -1,736 +0,0 @@
#include "positioning.hh"
template <class T>
inline T from_string(const string &s)
{
T t;
istringstream iss(s);
iss >> t;
return t;
}
void Positioning::makeReferencePointListFromFile(const string &filename, const bool uniq_point)
{
ifstream input_file ; // Flux d'entrée du fichier.
string cpp_buffer ; // Buffer au format string.
ReferencePoint rp;
Point tmp_point;
float x, y, z ; // Coordonnées des points.
unsigned int pt_idx = 0 ; // Position du point lu dans la liste.
int direction;
vector<string> infos ; // Liste des informations lues dans une ligne du fichier.
input_file.open(filename.c_str()) ;
if (input_file.fail())
{
cerr << "Error opening input file « " << filename << " » !" << endl ;
return ;
}
while (!input_file.eof())
{
getline(input_file, cpp_buffer);
if ((input_file.rdstate() & ifstream::eofbit) == 0)
{
if (cpp_buffer.size() == 0) // Ignorer une ligne vide
continue ;
infos = extractReferencePointInfoFromBuffer(cpp_buffer);
x = from_string<float>(infos[0]);
y = from_string<float>(infos[1]);
z = from_string<float>(infos[2]);
tmp_point.setX(x);
tmp_point.setY(y);
tmp_point.setZ(z);
direction = from_string<int>(infos[3]);
if (!uniq_point || !pointExists(reference_point_list, tmp_point)) // Si on ne veut pas de points unique, ou que le point n'existe pas encore,
{
rp.setCoordinates(tmp_point);
reference_point_list.push_back(rp); // on le crée.
pt_idx = reference_point_list.size() - 1; // Le point que l'on vient d'ajouter est le dernier du vector.
}
else // Le point existe déjà :
{
pt_idx = pointIndex(reference_point_list, tmp_point) ; // On recherche le point auquel on veut ajouter les informations.
}
for (unsigned int i = 4; i < infos.size(); i++)
{
if (i+1 < infos.size())
{
reference_point_list[pt_idx].addMeasurement(infos[i], from_string<int>(infos[i+1]));
i++;
}
}
}
}
input_file.close();
infos.clear() ;
}
void Positioning::makeApListFromFile(const string &filename)
{
ifstream input_file;
string buffer;
vector<string> ap_infos;
AccessPoint tmp_ap;
input_file.open(filename.c_str());
if (input_file.fail())
{
cerr << "Error opening input file « " << filename << " » !" << endl ;
return ;
}
while (!input_file.eof())
{
getline(input_file, buffer);
if ((input_file.rdstate() & ifstream::eofbit) == 0)
{
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
continue;
ap_infos = explode(buffer, ';');
tmp_ap.setApAddr(ap_infos[0]);
tmp_ap.setCoordinates(from_string<float>(ap_infos[1]), from_string<float>(ap_infos[2]), from_string<float>(ap_infos[3]));
tmp_ap.setFrequency(from_string<unsigned int>(ap_infos[4]));
tmp_ap.setAntennaGain(from_string<float>(ap_infos[5]));
tmp_ap.setOutputPower(from_string<float>(ap_infos[6]));
access_point_list.push_back(tmp_ap);
ap_infos.clear();
}
}
input_file.close();
}
void Positioning::makeTopologyFromFile(const string &filename)
{
ifstream input_file;
string buffer;
vector<string> infos;
input_file.open(filename.c_str()) ;
if (input_file.fail())
{
cerr << "Error opening input file « " << filename << " » !" << endl ;
return ;
}
while (!input_file.eof())
{
getline(input_file, buffer) ;
if ((input_file.rdstate() & ifstream::eofbit) == 0)
{
/* Traitement basique des commentaires */
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
continue ; // ignorer cette ligne.
infos = explode(buffer, ';') ;
if (area_list.find(infos[0]) != area_list.end()) // Si la pièce existe déjà,
cerr << "Erreur ! Déclaration multiple de la zone « " << infos[0] << " »." << endl ; // on le signale ;
else // sinon on l'ajoute :
area_list[infos[0]] = Area(infos[0], from_string<float>(infos[1]), from_string<float>(infos[3]),
from_string<float>(infos[2]), from_string<float>(infos[4]),
from_string<float>(infos[5]), from_string<float>(infos[6])) ;
infos.clear() ;
}
}
input_file.close() ;
}
void Positioning::makeWaypointListFromFile(const string &filename)
{
ifstream input_file ;
string buffer;
vector<string> infos ;
set<Point> point_list ;
input_file.open(filename.c_str());
if (input_file.fail())
{
cerr << "Error opening input file « " << filename << " » !" << endl ;
return ;
}
while (!input_file.eof())
{
getline(input_file, buffer);
if ((input_file.rdstate() & ifstream::eofbit) == 0)
{
if (buffer[0] == '\0' || buffer[0] == '#') // ligne vide ou ligne commençant par #
continue;
infos = explode(buffer, ';') ;
Point tmp_pt(from_string<float>(infos[0]), from_string<float>(infos[1]), from_string<float>(infos[2])) ;
if (! point_list.insert(tmp_pt).second)
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
infos.clear() ;
}
}
input_file.close(); // Lecture du fichier terminée
makeWaypointMatrix(point_list);
}
void Positioning::makeReferencePointListFromDb(PGconn *conn, const bool uniq)
{
PGresult *res;
Point tmp_point;
ReferencePoint rp;
ostringstream oss;
string buf;
buf = "SELECT * FROM ref_point;";
res = PQexec(conn, buf.c_str());
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
}
else
{
int nbRes = PQntuples(res);
for (int i = 0; i < nbRes; i++)
{
tmp_point.setX(from_string<float>(PQgetvalue(res, i, 1)));
tmp_point.setY(from_string<float>(PQgetvalue(res, i, 2)));
tmp_point.setZ(from_string<float>(PQgetvalue(res, i, 3)));
if (!uniq || !pointExists(reference_point_list, tmp_point)) // Si on ne veut pas de points unique, ou que le point n'existe pas encore,
{
rp.setCoordinates(tmp_point);
reference_point_list.push_back(rp); // on le crée.
}
}
PQclear(res);
for (unsigned int i = 0; i < reference_point_list.size(); i++)
{
tmp_point = reference_point_list[i].getCoordinates();
oss << "SELECT ap.ap_addr, n.power ";
oss << "FROM ap, ref_packet n, ref_request r, ref_point p ";
oss << "WHERE ap.id_ap = n.id_ap ";
oss << "AND n.id_ref_request = r.id_ref_request ";
oss << "AND r.id_ref_point = p.id_ref_point ";
oss << "AND p.x = " << tmp_point.getX() << " ";
oss << "AND p.y = " << tmp_point.getY() << " ";
oss << "AND p.z = " << tmp_point.getZ() << ";";
buf = oss.str();
oss.str("");
res = PQexec(conn, buf.c_str());
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
}
else
{
nbRes = PQntuples(res);
for (int j = 0; j < nbRes; j++)
reference_point_list[i].addMeasurement(PQgetvalue(res, j, 0), from_string<int>(PQgetvalue(res, j, 1)));
}
PQclear(res);
}
}
}
void Positioning::makeApListFromDb(PGconn *conn)
{
PGresult *res;
AccessPoint tmp_ap;
string buf;
buf = "SELECT * FROM ap;";
res = PQexec(conn, buf.c_str());
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
}
else
{
int nbRes = PQntuples(res);
for (int i = 0; i < nbRes; i++)
{
tmp_ap.setApAddr(PQgetvalue(res, i, 1));
tmp_ap.setCoordinates(from_string<float>(PQgetvalue(res, i, 2)), from_string<float>(PQgetvalue(res, i, 3)), from_string<float>(PQgetvalue(res, i, 4)));
tmp_ap.setFriisIndex(from_string<float>(PQgetvalue(res, i, 5)));
tmp_ap.setOutputPower(from_string<float>(PQgetvalue(res, i, 8)));
tmp_ap.setAntennaGain(from_string<float>(PQgetvalue(res, i, 7)));
tmp_ap.setFrequency(from_string<unsigned int>(PQgetvalue(res, i, 6)));
access_point_list.push_back(tmp_ap);
}
}
PQclear(res);
}
void Positioning::makeTopologyFromDb(PGconn *conn)
{
PGresult *res;
string buf;
buf = "SELECT * FROM area;";
res = PQexec(conn, buf.c_str());
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
}
else
{
int nbRes = PQntuples(res);
for (int i = 0; i < nbRes; i++)
{
if (area_list.find(PQgetvalue(res, i, 1)) != area_list.end()) // Si la pièce existe déjà,
cerr << "Erreur ! Déclaration multiple de la zone « " << PQgetvalue(res, i, 1) << " »." << endl ; // on le signale ;
else
area_list[PQgetvalue(res, i, 1)] = Area(PQgetvalue(res, i, 1), from_string<float>(PQgetvalue(res, i, 2)), from_string<float>(PQgetvalue(res, i, 5)),
from_string<float>(PQgetvalue(res, i, 3)), from_string<float>(PQgetvalue(res, i, 6)),
from_string<float>(PQgetvalue(res, i, 4)), from_string<float>(PQgetvalue(res, i, 7)));
}
}
PQclear(res);
}
void Positioning::makeWaypointListFromDb(PGconn *conn)
{
PGresult *res;
string buf;
set<Point> point_list ;
buf = "SELECT * FROM waypoint;";
res = PQexec(conn, buf.c_str());
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
cerr << "Commande incorrecte: " << PQerrorMessage(conn);
}
else
{
int nbRes = PQntuples(res);
for (int i = 0; i < nbRes; i++)
{
Point tmp_pt(from_string<float>(PQgetvalue(res, i, 0)), from_string<float>(PQgetvalue(res, i, 1)), from_string<float>(PQgetvalue(res, i, 2)));
if (! point_list.insert(tmp_pt).second)
cerr << "Point " << tmp_pt << " non ajouté ! Peut-être est-il dupliqué ?" << endl ;
}
makeWaypointMatrix(point_list);
}
PQclear(res);
}
void Positioning::makeWaypointMatrix(set<Point> point_list)
{
unsigned int nb_pts = point_list.size() ; // Nombre de points
unsigned int cur_idx = 0 ; // Itérateur sur l'indice de la matrice.
waypoint_list.reserve(nb_pts) ; // Vector contenant tous les points (attribut du serveur)
waypoint_matrix = new float*[nb_pts] ; // Matrice (carrée) des distances entre les points de passage (attribut du serveur)
for (unsigned int i = 0 ; i < nb_pts ; i++) // Initialisation de la matrice :
{
waypoint_matrix[i] = new float[nb_pts] ;
for (unsigned int k = 0 ; k < nb_pts ; k++) // Initialisation des distances à -1
waypoint_matrix[i][k] = -1 ;
}
for (set<Point>::iterator it = point_list.begin() ; it != point_list.end() ; it++, cur_idx++) // Pour chaque point enregistré
{
waypoint_list.push_back(*it) ; // Ajout du point dans waypoint_list
waypoint_matrix[cur_idx][cur_idx] = 0 ; // La distance du point à lui-même est nulle
for (unsigned int k = 0 ; k < cur_idx ; k++) // Pour chacun des point précédent
{
if (inTheSameArea(waypoint_list[cur_idx], waypoint_list[k])) // Si le point est dans la même zone,
{
float dist = it->distance(waypoint_list[k]) ; // on calcule la distance
waypoint_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
waypoint_matrix[k][cur_idx] = dist ; // dans les deux sens.
}
}
}
bool comput_done = true ;
while (comput_done)
{
comput_done = false ;
for (unsigned int i = 0 ; i < nb_pts ; i++)
for (unsigned int j = 0 ; j < nb_pts ; j++)
if (waypoint_matrix[i][j] > 0)
for (unsigned int k = 0 ; k < nb_pts ; k++)
if (waypoint_matrix[j][k] > 0)
{
float tmp_dist = round_float((waypoint_matrix[j][k] + waypoint_matrix[i][j]), 2);
if (tmp_dist < round_float(waypoint_matrix[i][k], 2) || waypoint_matrix[i][k] == -1)
{
waypoint_matrix[i][k] = tmp_dist ;
comput_done = true ;
}
}
}
}
map<string, Area> Positioning::inWhichAreas(const Point &p)
{
map<string, Area> areas ;
for (map<string, Area>::iterator it = area_list.begin() ; it != area_list.end() ; it++)
if (it->second.containsPoint(p))
areas.insert(make_pair(it->first, it->second)) ;
return areas;
}
bool Positioning::inTheSameArea(const Point &p1, const Point &p2)
{
// Liste des zones comportant les points p1 et p2 :
map<string, Area> zones1(inWhichAreas(p1));
map<string, Area> zones2(inWhichAreas(p2));
if (zones1.size() == 0 || zones2.size() == 0)
{
return false;
}
for (map<string, Area>::iterator it1 = zones1.begin() ; it1 != zones1.end() ; it1++) // Parcours des zones :
for (map<string, Area>::iterator it2 = zones2.begin(); it2 != zones2.end(); it2++)
if (it1->second == it2->second)
{
return true;
}
return false ;
}
float Positioning::distanceTopology(const Point &p1, const Point &p2)
{
map<string, Area> zones1(inWhichAreas(p1));
map<string, Area> zones2(inWhichAreas(p2));
if (zones1.size() == 0 || zones2.size() == 0) // Si aucune zone ne contient p1 ou p2,
{
return -1;
}
Area z1(zones1.begin() -> second); // Première zone d'appartenance du point p1. // FIXME : vérifier toutes les zones
Area z2(zones2.begin() -> second);
vector<Point> connection;
/* *** Cas de la même zone *** */
if (z1 == z2) // Si les points sont dans la même zone,
{
return p1.distance(p2) ; // la distance entre eux est la distance euclidienne.
}
/* *** Cas de deux zones voisines (connectées directement) *** */
if ((connection = areaConnection(z1, z2)).size() != 0) // Si les points sont dans deux zones voisines,
{
// la distance entre eux est la distance euclidienne de chacun jusqu'au plus proche point de passage entre les deux zones.
float dist = p1.distance(connection[0]) + p2.distance(connection[0]) ;
for (unsigned int i = 1 ; i < connection.size() ; i++) // Recherche du point de passage offrant la plus courte distance
{
float tmp_dist = p1.distance(connection[i]) + p2.distance(connection[i]) ;
if (tmp_dist < dist)
dist = tmp_dist ;
}
return dist ;
}
/* *** Les points sont dans des zones non-voisines *** */
// Liste des points de passage appartenant respectivement à z1 et à z2.
vector<Point> wp_z1(areaConnection(z1));
vector<Point> wp_z2(areaConnection(z2));
// Indices des points de passage dans la liste :
int wp_z1_idx;
int wp_z2_idx = -1 ; // z2 ne peut pas être utilisé non initialisé, contrairement à ce que dit GCC, car dans le cas où il n'est pas initialisé on quitte la fonction avant de l'utiliser (cf. "return -1" un peu plus bas);
if (wp_z1.size() == 0 || wp_z2.size() == 0) // Si l'une des deux zones ne comporte aucun point de passage,
{
return -1 ; // on quitte (ceci ne devrait jamais se produire).
}
/* Première itération (voir explication de l'algorithme plus bas) */
unsigned int i1, i2 ;
for (i1 = 0 ; i1 < wp_z1.size() ; i1++) // Recherche des premiers indices valides (où il existe un chemin entre les points de passage)
{
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i1]) ;
for (i2 = 0 ; i2 < wp_z2.size() ; i2++)
{
wp_z2_idx = pointIndex(waypoint_list, wp_z2[i2]) ;
if (wp_z2_idx < 0)
continue ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] != -1) // Si c'est bon,
break ; // on arrête le parcours.
}
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] != -1) // Si c'est bon,
break ; // on arrête le parcours.
}
if (i1 >= wp_z1.size()) // Si on a parcouru tout le tableau sans trouver de chemin,
{
return -1 ; // on quitte.
}
float dist = p1.distance(wp_z1[i1]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[i2]);
float tmp_dist ;
for (unsigned int j = i2 + 1 ; j < wp_z2.size() ; j++) // Fin du parcours :
{
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1)
continue ;
tmp_dist = p1.distance(wp_z1[i1]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[j]) ;
if (tmp_dist < dist)
dist = tmp_dist ;
}
/* Itérations suivantes */
for (unsigned int i = i1 + 1 ; i < wp_z1.size() ; i++)
for (unsigned int j = 0 ; j < wp_z2.size() ; j++)
{
// Indice des points de passage wp_z1[i] et wp_z2[j] dans la liste des points de passage :
wp_z1_idx = pointIndex(waypoint_list, wp_z1[i]) ;
wp_z2_idx = pointIndex(waypoint_list, wp_z2[j]) ;
if (waypoint_matrix[wp_z1_idx][wp_z2_idx] == -1) // S'il n'existe aucun chemin entre les deux points de passage
continue ;
tmp_dist = p1.distance(wp_z1[i]) + waypoint_matrix[wp_z1_idx][wp_z2_idx] + p2.distance(wp_z2[j]) ;
if (tmp_dist < dist)
dist = tmp_dist ;
}
return dist ;
}
vector<Point> Positioning::areaConnection(const Area &z1, const Area &z2)
{
vector<Point> points ;
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.find(z1.getName()) != areas.end() && areas.find(z2.getName()) != areas.end())
points.push_back(waypoint_list[i]) ;
}
return points ;
}
vector<Point> Positioning::areaConnection(const Area &z)
{
vector<Point> points ;
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.find(z.getName()) != areas.end())
points.push_back(waypoint_list[i]) ;
}
return points ;
}
void Positioning::makeReferencePointDistances()
{
unsigned int nb_pts = reference_point_list.size() ; // Nombre de points à traiter.
reference_point_matrix = new float*[nb_pts] ; // Allocation de la première dimension.
for (unsigned int i = 0 ; i < nb_pts ; i++) // Initialisation de la matrice :
{
reference_point_matrix[i] = new float[nb_pts] ;
for (unsigned int k = 0; k < nb_pts; k++) // Initialisation des distances à -1
reference_point_matrix[i][k] = -1 ;
}
for (unsigned int cur_idx = 0 ; cur_idx < nb_pts ; cur_idx++)
{
reference_point_matrix[cur_idx][cur_idx] = 0 ; // La distance du point à lui-même est nulle
for (unsigned int k = 0 ; k < cur_idx ; k++) // Pour chacun des point précédent
{
float dist = distanceTopology((Point) reference_point_list[cur_idx], (Point) reference_point_list[k]) ; // On calcule la distance
reference_point_matrix[cur_idx][k] = dist ; // et on l'insère dans le tableau,
reference_point_matrix[k][cur_idx] = dist ; // dans les deux sens.
}
}
}
bool Positioning::checkTopology()
{
for (unsigned int i = 0 ; i < waypoint_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas(waypoint_list[i])) ;
if (areas.empty())
{
return false ;
}
}
for (unsigned int i = 0 ; i < reference_point_list.size() ; i++)
{
map<string, Area> areas(inWhichAreas((Point)reference_point_list[i])) ;
if (areas.empty())
{
return false ; // À modifier si on veut permettre aux points de référence de n'appartenir à aucune zone.
}
}
set<string> connected_areas ; // Liste des zones connectées à au moins une autre zone (on n'enregistre que le nom des zones, dupliquer toutes les zones étant inutile).
for (map<string, Area>::iterator it1 = area_list.begin() ; it1 != area_list.end() ; it1++)
for (map<string, Area>::iterator it2 = area_list.begin() ; it2 != area_list.end() ; it2++)
{
if (it1 == it2)
continue ;
vector<Point> connect(areaConnection(it1->second, it2->second)) ;
if (!connect.empty())
connected_areas.insert(it1->first) ; // Ajout de la zone à la liste des zones connectées.
}
if (connected_areas.size() != area_list.size())
{
return false ;
}
return true ;
}
inline bool Positioning::pointExists(const float &x, const float &y, const float &z) const
{
return pointExists(reference_point_list, Point(x, y, z));
}
inline bool Positioning::pointExists(const Point &p) const
{
return pointExists(reference_point_list, p);
}
inline bool Positioning::pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
{
return pointExists(point_list, Point(x, y, z));
}
inline bool Positioning::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
{
return (pointIndex(point_list, p) != -1);
}
inline int Positioning::pointIndex(const Point &p) const
{
return (unsigned int) pointIndex(reference_point_list, p);
}
inline int Positioning::pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const
{
return (unsigned int) pointIndex(point_list, Point(x, y, z)) ;
}
inline int Positioning::pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const
{
unsigned int i;
for (i = 0 ; i < point_list.size() ; i++)
if (p == point_list[i].getCoordinates())
{
return i;
}
return -1;
}
/* Retourne la position du Point "p" dans le tableau à une dimension "point_tab" de taille "size", ou -1 en cas d'échec. */
inline int Positioning::pointIndex(const Point *point_tab, unsigned int &size, const Point &p) const
{
for (unsigned int i = 0 ; i < size ; i++)
if (point_tab[i] == p)
return i;
return -1;
}
/* Retourne la position du Point "p" dans le vector "point_list", ou -1 en cas d'échec. */
inline int Positioning::pointIndex(const vector<Point> &point_list, const Point &p) const
{
for (unsigned int i = 0 ; i < point_list.size() ; i++)
if (point_list[i] == p)
{
return i;
}
return -1;
}
void Positioning::printReferencePointList()
{
printPointList(reference_point_list) ;
}
void Positioning::printPointList(vector<ReferencePoint> &point_list)
{
for (unsigned int i = 0 ; i < point_list.size() ; i++)
cout << point_list[i] << endl ;
}
void Positioning::printAccessPointList() const
{
for (unsigned int i = 0; i < access_point_list.size(); i++)
cout << access_point_list[i] << endl;
}
void Positioning::printAreatList()
{
for (map<string, Area>::iterator it = area_list.begin() ; it != area_list.end() ; it++)
cout << it -> second << endl;
}

View File

@ -1,73 +0,0 @@
#ifndef _POSITIONING_HH_
#define _POSITIONING_HH_
#include "point.hh"
#include "referencepoint.hh"
#include "accesspoint.hh"
#include "area.hh"
#include "measurement.hh"
#include "libowlps-positioning.hh"
class Positioning
{
private:
vector<ReferencePoint> reference_point_list; // Liste des points de référence (calibration).
float** reference_point_matrix; // Matrice des distances entre les points de référence.
vector<AccessPoint> access_point_list; // Liste des AP connus.
vector<Point> waypoint_list; // Liste des points de passage entre les zones.
float** waypoint_matrix; // Matrice des distances entre les points de passage.
map<string, Area> area_list ; // Liste des zones homogènes (pièces).
public :
Positioning() {};
~Positioning() {};
void makeReferencePointListFromFile(const string &filename, const bool);
void makeApListFromFile(const string &filename);
void makeTopologyFromFile(const string &filename);
void makeWaypointListFromFile(const string &filename);
void makeReferencePointListFromDb(PGconn*, const bool);
void makeApListFromDb(PGconn*);
void makeTopologyFromDb(PGconn*);
void makeWaypointListFromDb(PGconn*);
void makeWaypointMatrix(set<Point>);
map<string, Area> inWhichAreas(const Point &p);
bool inTheSameArea(const Point &p1, const Point &p2);
float distanceTopology(const Point &p1, const Point &p2);
vector<Point> areaConnection(const Area &z1, const Area &z2);
vector<Point> areaConnection(const Area &z);
void makeReferencePointDistances();
bool checkTopology();
bool pointExists(const float &x, const float &y, const float &z)const;
bool pointExists(const Point &p)const;
bool pointExists(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const ;
bool pointExists(const vector<ReferencePoint> &point_list, const Point &p) const ;
int pointIndex(const float &x, const float &y, const float &z) const;
int pointIndex(const Point &p) const;
int pointIndex(const vector<ReferencePoint> &point_list, const float &x, const float &y, const float &z) const ;
int pointIndex(const vector<ReferencePoint> &point_list, const Point &p) const ;
int pointIndex(const Point *tab, unsigned int &size, const Point &p) const ;
int pointIndex(const vector<Point> &point_list, const Point &p) const ;
vector<AccessPoint> getAccessPointList() const
{
return access_point_list;
};
vector<ReferencePoint> getReferencePointList() const
{
return reference_point_list;
};
void printReferencePointList();
void printPointList(vector<ReferencePoint> &point_list);
void printAccessPointList() const;
void printAreatList();
};
#endif // _POSITIONING_HH_

View File

@ -1,311 +0,0 @@
#include "server.hh"
/* Transforme un string en un type différent */
template <class T>
inline T from_string(const string &s)
{
T t;
istringstream iss(s);
iss >> t;
return t;
}
/* Initialisation du serveur */
int Server::init(const boost::program_options::variables_map vm)
{
ostringstream oss;
string buf;
/* Connexion à la BdD */
oss << "hostaddr = '";
if (vm.count("db.host")) // Recherche du nom de l'hôte de la BdD
oss << vm["db.host"].as<string>();
else
{
cerr << "Attention ! Hôte de la BDD non spécifié, utilisation de la valeur par défaut..." << endl ;
oss << DEFAULT_BDD_HOST;
}
oss << "' dbname = '";
if (vm.count("db.name")) // Recherche du nom de la BdD
oss << vm["db.name"].as<string>();
else
{
cerr << "Attention ! Nom de la BDD non spécifié, utilisation de la valeur par défaut..." << endl ;
oss << DEFAULT_BDD_NAME;
}
oss << "' user = '";
if (vm.count("db.user")) // Recherche du nom d'utilisateur de la BdD
oss << vm["db.user"].as<string>();
else
{
cerr << "Attention ! Utilisateur non spécifié pour la connexion à la BDD, utilisation de la valeur par défaut..." << endl ;
oss << DEFAULT_BDD_USER;
}
oss << "' password = '";
if (vm.count("db.passwd")) // Recherche du mot de passe
oss << vm["db.passwd"].as<string>() << "'";
else
{
cerr << "Attention ! Mot de passe non spécifié pour la connexion à la BDD, utilisation de la valeur par défaut..." << endl ;
oss << DEFAULT_BDD_PASS << "'";
}
buf = oss.str();
const char *conninfo = buf.c_str();
conn = PQconnectdb(conninfo);
if (PQstatus(conn) != CONNECTION_OK)
{
cout << "Erreur ! Connexion à la base de donnée échouée : " << PQerrorMessage(conn) << endl;
return 1;
}
/* Création de la topology */
if (vm.count("input-topo")) pos.makeTopologyFromFile(vm["input-topo"].as<string>());
else pos.makeTopologyFromDb(conn);
/* Création de la liste des points de passage */
if (vm.count("input-waypoint")) pos.makeWaypointListFromFile(vm["input-waypoint"].as<string>());
else pos.makeWaypointListFromDb(conn);
/* Création de la liste des points de référence */
if (vm.count("input-refpoint")) pos.makeReferencePointListFromFile(vm["input-refpoint"].as<string>(), true);
else pos.makeReferencePointListFromDb(conn, true);
if (!pos.checkTopology())
{
cerr << "Erreur lors de la création de la topologie !" << endl;
return 1;
}
pos.makeReferencePointDistances();
/* Création de la liste des Access Point */
if (vm.count("input-ap"))
pos.makeApListFromFile(vm["input-ap"].as<string>()) ;
else
pos.makeApListFromDb(conn) ;
return 0;
}
int Server::start()
{
struct sockaddr_in serv_addr;
struct sockaddr_in client;
socklen_t client_len = sizeof(client);
Point solution;
char *mac = (char *) malloc(18 * sizeof(char));
/* Création d'une socket UDP */
listen_socket = socket(AF_INET, SOCK_DGRAM, 0) ;
if (listen_socket < 0)
{
cerr << "Échec de la création de la socket " << endl;
exit(1);
}
/* Remise à zéro et initialisation de la structure du serveur */
bzero((char *) &serv_addr, sizeof(serv_addr)) ; // RÀZ
serv_addr.sin_family = AF_INET ; // Socket INET
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions sont acceptées
serv_addr.sin_port = htons(listen_port) ; // Port d'écoute
/* Réservation du port */
if (bind(listen_socket, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
cerr << "Impossible de créer la socket (bind) " << endl;
close(listen_socket) ;
exit(1);
}
cout << "Serveur prêt" << endl;
/* Récupération des données envoyées par le client */
while (true)
{
/* Attente d'une demande d'un serveur d'aggrégation */
if (recvfrom(listen_socket, &att_request, sizeof(att_request), 0, (struct sockaddr *) &client, &client_len) < 0)
{
cerr << "Aucun message reçu du client" << endl;
close(listen_socket);
return 1;
}
recv_info.resize(att_request.nb_couples);
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", att_request.mobile_mac_addr_bytes[0],att_request.mobile_mac_addr_bytes[1],
att_request.mobile_mac_addr_bytes[2],att_request.mobile_mac_addr_bytes[3],
att_request.mobile_mac_addr_bytes[4],att_request.mobile_mac_addr_bytes[5]);
cout << "\n*** Message reçu de l'aggregator ***" << endl;
cout << "\tMAC Mobile\t: " << mac << endl;
cout << "\tHeure de la demande\t: " << timeval_to_ms(att_request.request_time) << endl;
cout << "\tNombre de couples\t: " << att_request.nb_couples << endl;
/* Récupération des couples (AP;Puissance) */
for (int i = 0; i < att_request.nb_couples; i++)
recvfrom(listen_socket, &recv_info.at(i), sizeof(couple_info), 0, (struct sockaddr *) &client, &client_len);
treatment();
recv_info.clear();
}
}
/* Calcul de la position avec les différents algo */
void Server::treatment()
{
Point solution;
int id_request; // Permet de récupérer l'id de la requête pour lui assigner les résultats
char *mac = (char *) malloc(18 * sizeof(char));
ostringstream oss;
PGresult *res;
/* */
Treatment treat(pos.getAccessPointList(), pos.getReferencePointList());
treat.makeMeasurementList(recv_info);
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", att_request.mobile_mac_addr_bytes[0],att_request.mobile_mac_addr_bytes[1],
att_request.mobile_mac_addr_bytes[2],att_request.mobile_mac_addr_bytes[3],
att_request.mobile_mac_addr_bytes[4],att_request.mobile_mac_addr_bytes[5]);
oss << "SELECT r.id_request FROM request r, mobile m ";
oss << "WHERE r.mobile_time = " << timeval_to_ms(att_request.request_time);
oss << " AND m.id_mobile = r.id_mobile";
oss << " AND m.mobile_addr = '" << mac << "';"; // On recherche dans la BdD la requête consernée
res = PQexec(conn, oss.str().c_str());
id_request = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)): -1; // On conserve l'id de la requête
PQclear(res);
/* Interlink Networks */
solution = treat.interlink(0) ;
createResult(solution, id_request, "Interlink Network");
/* RADAR */
solution = treat.getkClosestInSs(1, NULL)[0] ;
createResult(solution, id_request, "Radar");
/* FBCM */
solution = treat.fbcm(0) ;
createResult(solution, id_request, "FCBM");
/* 1-NSS + FBCM */
solution = treat.getkClosestInSs(1, NULL)[0] ;
solution = treat.fbcm_friis(treat.computeFriisFromRefList(solution), solution.getZ()) ;
createResult(solution, id_request, "1-NSS + FBCM");
/* 2-NSS */
solution = treat.getkWeightedInSs(2, NULL);
createResult(solution, id_request, "2-NSS");
/* 3-NSS */
solution = treat.getkWeightedInSs(3, NULL);
createResult(solution, id_request, "3-NSS");
/* 5-NSS */
solution = treat.getkWeightedInSs(5, NULL);
createResult(solution, id_request, "5-NSS");
sendToClient(solution, mac);
free(mac);
}
/* Enregistrement du résultat dans la BdD */
void Server::createResult(Point solution, int id_request, string use_algo)
{
int id_result;
string buf;
ostringstream oss;
struct timeval current;
PGresult *res;
gettimeofday(&current, NULL); // On récupère l'heure du calcul
buf = "SELECT * FROM result;";
res = PQexec(conn, buf.c_str());
id_result = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)) + 1: 1;
oss << "INSERT INTO result(id_result, x, y, z, calcul_date, using_algo";
if (id_request != -1) oss << ", id_request"; // Si la requête n'a pas été trouvé, on enregistre le résultat mais sans associé de requête
oss << ") VALUES('";
oss << id_result << "','" << solution.getX() << "','" << solution.getY() << "','" << solution.getZ();
oss << "','" << timeval_to_ms(current) << "','" << use_algo;
if (id_request != -1) oss << "','" << id_request;
oss << "');";
PQexec(conn, oss.str().c_str());
PQclear(res);
}
void Server::sendToClient(Point solution, char *mac)
{
int sockfd ; // Descripteur de la socket
struct sockaddr_in serv;
struct sockaddr_in mobile;
socklen_t mobile_len = sizeof(mobile);
ostringstream oss;
float x,y,z;
PGresult *res;
oss << "SELECT ip_mobile FROM mobile ";
oss << "WHERE mobile_addr = '" << mac << "';"; // On récupére l'adresse IP du mobile
res = PQexec(conn, oss.str().c_str());
if (PQntuples(res) != 0)
{
/* Ceation de la socket UDP */
sockfd = socket(AF_INET, SOCK_DGRAM, 0) ;
if (sockfd < 0)
{
cerr << "Échec de la création de la socket " << endl;
exit(1);
}
/* Remise à zéro et initialisation de la structure du server */
bzero((char *) &serv, sizeof(serv)) ;
serv.sin_family = AF_INET ; // Socket INET
serv.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions
/* Remise à zéro et initialisation de la structure du mobile */
bzero((char *) &mobile, sizeof(mobile)) ; // RÀZ
mobile.sin_family = AF_INET ; // Socket INET
mobile.sin_addr.s_addr = inet_addr(PQgetvalue(res, 0, 0)) ;
mobile.sin_port = htons(mobile_port) ;
x = solution.getX();
y = solution.getY();
z = solution.getZ();
/* On envoie les coordonnées de la position */
sendto(sockfd, (void *)&x, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
sendto(sockfd, (void *)&y, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
sendto(sockfd, (void *)&z, sizeof(float), 0, (struct sockaddr *)&mobile, mobile_len);
close(sockfd);
cout << "Envoi de la position au client " << mac << " à l'adresse IP " << PQgetvalue(res, 0, 0) << endl;
}
PQclear(res);
}

View File

@ -1,53 +0,0 @@
#ifndef _SERVER_HH_
#define _SERVER_HH_
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <sys/types.h>
#include <boost/program_options.hpp>
#include "point.hh"
#include "positioning.hh"
#include "measurement.hh"
#include "treatment.hh"
#include "libowlps-positioning.hh"
class Server
{
private:
request att_request;
vector<couple_info> recv_info;
int listen_port;
int mobile_port;
int listen_socket;
PGconn *conn;
Positioning pos;
public:
Server(int port, int mport)
{
listen_port = port;
mobile_port = mport;
};
~Server()
{
close(listen_socket);
PQfinish(conn);
};
int start();
int init(const boost::program_options::variables_map);
void treatment();
void createResult(Point, int, string);
void sendToClient(Point, char *);
};
#endif // _SERVER_HH_

View File

@ -1,416 +0,0 @@
#include "treatment.hh"
bool Treatment::apExists(const string &ap_addr)const
{
string str;
for (unsigned int i = 0 ; i < access_point_list.size() ; i++)
{
str = access_point_list[i].getApAddr() ;
const int length = str.length() ;
for (int j = 0 ; j < length ; ++j)
str[j] = tolower(str[j]) ;
if (str == ap_addr)
{
return true ;
}
}
return false ;
}
unsigned int Treatment::apIndex(const string &ap_addr)const
{
unsigned int i;
string str;
for (i = 0 ; i < access_point_list.size() ; i++)
{
str = access_point_list[i].getApAddr() ;
const int length = str.length() ;
for (int j = 0 ; j < length ; ++j)
str[j] = tolower(str[j]) ;
if (str == ap_addr)
{
return i;
}
}
return 0; // Should never happen
}
void Treatment::makeMeasurementList(vector<couple_info> recv_info)
{
bool inserted = false;
Measurement measure;
char *ret = (char *)malloc(sizeof(char) * 18) ;
string mac_a;
int value;
for (unsigned int i = 0; i < recv_info.size(); i++)
{
sprintf(ret, "%02x:%02x:%02x:%02x:%02x:%02x", recv_info.at(i).ap_mac_addr_bytes[0], recv_info.at(i).ap_mac_addr_bytes[1], recv_info.at(i).ap_mac_addr_bytes[2], recv_info.at(i).ap_mac_addr_bytes[3], recv_info.at(i).ap_mac_addr_bytes[4], recv_info.at(i).ap_mac_addr_bytes[5]) ;
ret[17] = '\0';
mac_a = ret;
value = recv_info.at(i).antenna_signal_dbm;
for (unsigned int j = 0 ; j < m.size() ; j++)
if (m[j].getMacAddr() == mac_a)
{
m[j].addSsValue(value);
inserted = true;
break;
}
if (inserted == false)
{
measure.setMacAddr(mac_a);
measure.addSsValue(value);
m.push_back(measure);
}
}
free(ret);
}
vector<Point> Treatment::getkClosestInSs(const unsigned int &k, const Point *point_ignored)const
{
unsigned int i, j, min_idx;
vector<float> distances_vector;
vector<Point> points_vector;
Point tmp_pt;
float tmp_distance = 0, dist_max = 10000000, tmp_min;
for (i = 0 ; i < reference_point_list.size() ; i++)
if (point_ignored == NULL || (reference_point_list[i].getCoordinates() != *point_ignored))
{
tmp_distance = reference_point_list[i].getSsSquareDistance(m);
/* if not k points, add it */
if (distances_vector.size() < k)
{
distances_vector.push_back(tmp_distance);
points_vector.push_back(reference_point_list[i].getCoordinates());
dist_max = (dist_max < tmp_distance) ? tmp_distance : dist_max;
}
else
{
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
if (dist_max > tmp_distance)
{
/* remove old max */
for (j = 0 ; j < distances_vector.size() ; j++)
if (distances_vector[j] == dist_max)
{
distances_vector[j] = tmp_distance;
points_vector[j] = reference_point_list[i].getCoordinates();
break;
}
/* Now seek the new max. distance */
dist_max = distances_vector[0];
for (j = 1 ; j < distances_vector.size() ; j++)
if (distances_vector[j] > dist_max)
dist_max = distances_vector[j];
}
/* Else nothing needs to be done */
}
}
/* Sorts the vector */
for (i = 0 ; i < distances_vector.size() - 1 ; i++)
{
tmp_min = distances_vector[i];
min_idx = i;
for (j = i+1 ; j < distances_vector.size() ; j++)
if (tmp_min > distances_vector[j])
{
tmp_min = distances_vector[j];
min_idx = j;
}
if (min_idx != i)
{
/* Swap points */
tmp_pt = points_vector[i];
points_vector[i] = points_vector[min_idx];
points_vector[min_idx] = tmp_pt;
/* Swap distances */
distances_vector[min_idx] = distances_vector[i];
distances_vector[i] = tmp_min;
}
}
return points_vector;
}
Point Treatment::fbcm(const int &client_idx)const
{
Point ret(0, 0, 0);
vector<string> addr;
vector<float> dist_vect;
vector<Point> centres;
unsigned int i, ap_idx;
float constant_term, minmax_res, minmax_max;
float x = MINMAX_X_START, y = MINMAX_Y_START, z = MINMAX_Z_START;
i = 0;
//cout << "FBCM: ";
for (i = 0 ; i < m.size() ; i++)
if (apExists(m[i].getMacAddr()))
{
ap_idx = apIndex(m[i].getMacAddr());
//cout << "AP idx: " << ap_idx << " ";
centres.push_back(access_point_list[ap_idx].getCoordinates());
addr.push_back(m[i].getMacAddr());
constant_term = access_point_list[ap_idx].getOutputPower() + access_point_list[ap_idx].getAntennaGain() + 2;
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI));
//end of expr. should be: client_list[client_idx].getAntennaGain() instead of 2.
//cout << "20log(" << (300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI) << ") = ";
//cout << constant_term << " ";
dist_vect.push_back(pow(10, (constant_term - m[i].getAverage()) / (10 * access_point_list[ap_idx].getFriisIndex())));
//cout << endl;
}
/* Then: min-max */
minmax_res = 1000000;
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
for (z = MINMAX_Z_START ; z <= MINMAX_Z_STOP ; z += MINMAX_STEP)
{
minmax_max = 0;
for (i = 0 ; i < centres.size() ; i++)
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]) ;
if (minmax_max < minmax_res)
{
ret.setX(x);
ret.setY(y);
ret.setZ(z);
minmax_res = minmax_max;
}
}
/* Clear all vectors */
addr.clear();
dist_vect.clear();
centres.clear();
/* Return position */
return ret;
}
Point Treatment::fbcm_friis(const vector<float> friis_idx_list, const float &z)const
{
Point ret(0, 0, 0);
vector<float> dist_vect;
vector<Point> centres;
unsigned int i, ap_idx;
float constant_term, minmax_res, minmax_max;
float x = MINMAX_X_START, y = MINMAX_Y_START ;
vector<Measurement> vm = m; //Used when filtering 3 strongest APs
vector<float> friis_idx = friis_idx_list; //Used when filtering 3 strongest APs
i = 0;
for (i = 0 ; i < vm.size() ; i++)
{
if (apExists(vm[i].getMacAddr()))
{
ap_idx = apIndex(vm[i].getMacAddr());
constant_term = access_point_list[ap_idx].getOutputPower() + access_point_list[ap_idx].getAntennaGain() + 2;
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI));
if (friis_idx[i] != -1)
{
centres.push_back(access_point_list[ap_idx].getCoordinates());
dist_vect.push_back(pow(10, (constant_term - vm[i].getAverage()) / (10 * friis_idx[i])));
}
}
}
/* Then: min-max */
minmax_res = 1000000;
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
{
minmax_max = 0;
for (i = 0 ; i < centres.size() ; i++)
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]) ;
if (minmax_max < minmax_res)
{
ret.setX(x);
ret.setY(y);
ret.setZ(z);
minmax_res = minmax_max;
}
}
/* Clear all vectors */
dist_vect.clear();
centres.clear();
/* Return position */
return ret;
}
Point Treatment::interlink(const int &client_idx) const
{
Point ret(0, 0, 0);
vector<string> addr;
vector<float> dist_vect;
vector<Point> centres;
unsigned int i, ap_idx;
float constant_term, minmax_res, minmax_max;
float x = MINMAX_X_START, y = MINMAX_Y_START, z = MINMAX_Z_START;
i = 0;
for (i = 0 ; i < m.size() ; i++)
if (apExists(m[i].getMacAddr()))
{
ap_idx = apIndex(m[i].getMacAddr());
centres.push_back(access_point_list[ap_idx].getCoordinates());
addr.push_back(m[i].getMacAddr());
constant_term = access_point_list[ap_idx].getOutputPower() + access_point_list[ap_idx].getAntennaGain();
constant_term += 20 * log10((300000000.0 / (float) access_point_list[ap_idx].getFrequency()) / (4*M_PI)) + 2;
//end of expr. should be: client_list[client_idx].getAntennaGain() instead of 2.
dist_vect.push_back(pow(10, (constant_term - m[i].getAverage()) / 35));
}
/* Then: min-max */
minmax_res = 1000000;
for (x = MINMAX_X_START ; x < MINMAX_X_STOP ; x += MINMAX_STEP)
for (y = MINMAX_Y_START ; y < MINMAX_Y_STOP ; y += MINMAX_STEP)
for (z = MINMAX_Z_START ; z < MINMAX_Z_STOP ; z += MINMAX_STEP)
{
minmax_max = 0;
for (i = 0 ; i < centres.size() ; i++)
if (abs(centres[i].distance(x, y, z) - dist_vect[i]) > minmax_max)
minmax_max = abs(centres[i].distance(x, y, z) - dist_vect[i]);
if (minmax_max < minmax_res)
{
ret.setX(x);
ret.setY(y);
ret.setZ(z);
minmax_res = minmax_max;
}
}
/* Clear all vectors */
addr.clear();
dist_vect.clear();
centres.clear();
/* Return position */
return ret;
}
vector<float> Treatment::computeFriisFromRefList(const Point &p)
{
vector<float> friis_idx_list;
Point pt_coords, ap_coords;
float ap_power, ap_gain, calib_gain = 2, const_term, mes_power/*, friis_sum*/;
unsigned int ap_freq;
string ap_mac;
/* Compute an index for each ref point. List stored in friis_idx_list */
/* Compute an index for Point p. List stored in friis_idx_list */
for (unsigned int j = 0 ; j < reference_point_list.size() ; j++)
{
pt_coords = reference_point_list[j].getCoordinates();
if (pt_coords==p)
{
for (unsigned int i = 0 ; i < m.size() ; i++)
{
if (apExists(m[i].getMacAddr()))
{
unsigned int ap_idx = apIndex(m[i].getMacAddr());
ap_power = access_point_list[ap_idx].getOutputPower();
ap_coords = access_point_list[ap_idx].getCoordinates();
ap_freq = access_point_list[ap_idx].getFrequency();
ap_gain = access_point_list[ap_idx].getAntennaGain();
ap_mac = access_point_list[ap_idx].getApAddr();
/* Compute main general term, independant from scans */
const_term = calib_gain + ap_gain;
const_term -= 20 * log10(4 * M_PI);
const_term += 20 * log10 (300000000.0 / ap_freq) + ap_power;
if (reference_point_list[j].getPowerForAp(ap_mac, &mes_power))
friis_idx_list.push_back((const_term - mes_power) / (10 * log10(ap_coords.distance(pt_coords))));
else
friis_idx_list.push_back(-1);
}
}
break;
}
}
return friis_idx_list;
}
Point Treatment::getkWeightedInSs(const unsigned int &k, const Point *point_ignored)const
{
unsigned int i, j;
vector<float> distances_vector;
vector<Point> points_vector;
float tmp_distance = 0, dist_max = 10000000;
Point ret;
float total = 0, x = 0, y = 0, z = 0;
for (i = 0 ; i < reference_point_list.size() ; i++)
if (point_ignored == NULL || (reference_point_list[i].getCoordinates() != *point_ignored))
{
tmp_distance = reference_point_list[i].getSsSquareDistance(m);
/* if not k points, add it */
if (distances_vector.size() < k)
{
distances_vector.push_back(tmp_distance);
points_vector.push_back(reference_point_list[i].getCoordinates());
dist_max = (dist_max < tmp_distance) ? tmp_distance : dist_max;
}
else
{
/* if tmp_dst < dist_max, should add it and remove previous greatest dist. */
if (dist_max > tmp_distance)
{
/* remove old max */
for (j = 0 ; j < distances_vector.size() ; j++)
if (distances_vector[j] == dist_max)
{
dist_max = tmp_distance;
distances_vector.erase(distances_vector.begin() + j);
points_vector.erase(points_vector.begin() + j);
distances_vector.push_back(tmp_distance);
points_vector.push_back(reference_point_list[i].getCoordinates());
break;
}
}
/* Else nothing needs to be done */
}
}
for (i = 0 ; i < distances_vector.size() ; i++)
total += (1 / distances_vector[i]);
for (i = 0 ; i < distances_vector.size() ; i++)
{
x += points_vector[i].getX() * (1 / distances_vector[i]) / total;
y += points_vector[i].getY() * (1 / distances_vector[i]) / total;
z += points_vector[i].getZ() * (1 / distances_vector[i]) / total;
}
ret.setX(x);
ret.setY(y);
ret.setZ(z);
return ret;
}

View File

@ -1,45 +0,0 @@
#ifndef _TREATMENT_HH_
#define _TREATMENT_HH_
#include "point.hh"
#include "measurement.hh"
#include "accesspoint.hh"
#include "referencepoint.hh"
#include "libowlps-positioning.hh"
class Treatment
{
private:
vector<AccessPoint> access_point_list;
vector<ReferencePoint> reference_point_list;
vector<Measurement> m;
public:
Treatment(vector<AccessPoint> access_point, vector<ReferencePoint> reference_point)
{
access_point_list = access_point;
reference_point_list = reference_point;
};
~Treatment()
{
access_point_list.clear();
m.clear();
reference_point_list.clear();
};
bool apExists(const string &)const;
unsigned int apIndex(const string &)const;
void makeMeasurementList(vector<couple_info>);
vector<Point> getkClosestInSs(const unsigned int &k, const Point *point_ignored)const;
Point kPointsAverage(const vector<Point> &vp)const;
Point fbcm(const int &client_idx)const;
Point fbcm_friis(const vector<float> friis_idx_list, const float &z)const;
Point interlink(const int &client_idx)const;
vector<float> computeFriisFromRefList(const Point &p);
Point getkWeightedInSs(const unsigned int &k, const Point *point_ignored)const ;
};
#endif // _TREATMENT_HH_