[Positioning] Add Configuration and UserInterface
- Add class Configuration, a stock for the configuration structure. - Add class UserInterface, that handles the configuration input. - Update owlps-positioning.cc (delete old stuff like configuration) and delete owlps-positioning.hh: we now have a compilable executable.
This commit is contained in:
parent
12d14b805f
commit
9cf4daca3b
|
@ -1,3 +1,4 @@
|
||||||
*~
|
*~
|
||||||
*.o
|
*.o
|
||||||
*.swp
|
*.swp
|
||||||
|
*.orig
|
||||||
|
|
|
@ -2,3 +2,4 @@ doc
|
||||||
csv/*.csv
|
csv/*.csv
|
||||||
tests/*.cc
|
tests/*.cc
|
||||||
tests/tests
|
tests/tests
|
||||||
|
owlps-positioning
|
||||||
|
|
|
@ -17,7 +17,7 @@ RM_RECURSIVE = \rm -fr
|
||||||
CP = cp -v
|
CP = cp -v
|
||||||
|
|
||||||
# Autres outils
|
# Autres outils
|
||||||
STYLE = astyle --style=gnu
|
STYLE = astyle --style=gnu --formatted
|
||||||
CPPCHECK = cppcheck --enable=all
|
CPPCHECK = cppcheck --enable=all
|
||||||
DOXYGEN = doxygen
|
DOXYGEN = doxygen
|
||||||
|
|
||||||
|
@ -26,20 +26,20 @@ GXX = g++-4.4
|
||||||
TESTSGXXFLAGS = -I$(TEST_DIR) -I.
|
TESTSGXXFLAGS = -I$(TEST_DIR) -I.
|
||||||
GXXFLAGS = $(DEBUG) -Wall -Wextra $(STLPORTGXXFLAGS)
|
GXXFLAGS = $(DEBUG) -Wall -Wextra $(STLPORTGXXFLAGS)
|
||||||
LD = $(GXX)
|
LD = $(GXX)
|
||||||
LDFLAGS = -lm -lrt
|
LDFLAGS = -lm -lrt -lboost_program_options
|
||||||
LIBS = -lpq -lboost_program_options-mt
|
#LIBS = -lpq
|
||||||
|
|
||||||
TARGET = owlps-positioning
|
TARGET = owlps-positioning
|
||||||
#HEADER = owlps-positioning.hh
|
#HEADER = owlps-positioning.hh
|
||||||
OBJ = posutil.o stock.o timestamp.o point3d.o referencepoint.o \
|
OBJ = posutil.o stock.o timestamp.o point3d.o referencepoint.o \
|
||||||
waypoint.o building.o area.o wifidevice.o accesspoint.o \
|
waypoint.o building.o area.o wifidevice.o accesspoint.o \
|
||||||
mobile.o measurement.o calibrationmeasurement.o request.o \
|
mobile.o measurement.o calibrationmeasurement.o request.o \
|
||||||
inputcsv.o
|
inputcsv.o configuration.o userinterface.o
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
%: %.o
|
%: %.o
|
||||||
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(LD) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
%.o: %.cc $(HEADER)
|
%.o: %.cc $(HEADER)
|
||||||
$(GXX) $(GXXFLAGS) -c $<
|
$(GXX) $(GXXFLAGS) -c $<
|
||||||
|
@ -49,6 +49,8 @@ $(TEST_DIR)/%_test.o: %.o
|
||||||
|
|
||||||
posutil.o: posutil.hh
|
posutil.o: posutil.hh
|
||||||
stock.o: stock.hh
|
stock.o: stock.hh
|
||||||
|
configuration.o: configuration.hh
|
||||||
|
userinterface.o: userinterface.hh configuration.o
|
||||||
timestamp.o: timestamp.hh
|
timestamp.o: timestamp.hh
|
||||||
point3d.o: point3d.hh
|
point3d.o: point3d.hh
|
||||||
referencepoint.o : referencepoint.hh point3d.o
|
referencepoint.o : referencepoint.hh point3d.o
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
utilisant les champs de direction.
|
utilisant les champs de direction.
|
||||||
° Lire la direction en tant qu'entier plutôt que float ?
|
° Lire la direction en tant qu'entier plutôt que float ?
|
||||||
|
|
||||||
|
- Tests unitaires
|
||||||
|
Écrire une classe utilitaire pour les tests contenant par exemple
|
||||||
|
une fonction pour écrire un fichier de test à partir d'un
|
||||||
|
vector<string>.
|
||||||
|
|
||||||
- Réorganisation du dépôt ?
|
- Réorganisation du dépôt ?
|
||||||
owlps-positioning/src
|
owlps-positioning/src
|
||||||
owlps-positioning/include
|
owlps-positioning/include
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "configuration.hh"
|
||||||
|
|
||||||
|
namespace po = boost::program_options ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Attribute definitions *** */
|
||||||
|
|
||||||
|
po::variables_map Configuration::configuration ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Read accessors *** */
|
||||||
|
|
||||||
|
|
||||||
|
po::variables_map& Configuration::getw_configuration()
|
||||||
|
{
|
||||||
|
return configuration ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Configuration::is_configured(const std::string &key)
|
||||||
|
{
|
||||||
|
if (configuration.count(key))
|
||||||
|
return true ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::string&
|
||||||
|
Configuration::get_string_value(const std::string &key)
|
||||||
|
{
|
||||||
|
return configuration[key].as<std::string>() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Configuration::get_int_value(const std::string &key)
|
||||||
|
{
|
||||||
|
return configuration[key].as<int>() ;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef _OWLPS_POSITIONING_CONFIGURATION_HH_
|
||||||
|
#define _OWLPS_POSITIONING_CONFIGURATION_HH_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/program_options/variables_map.hpp>
|
||||||
|
|
||||||
|
/// Stocks the configuration of the program
|
||||||
|
class Configuration
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// Configuration structure
|
||||||
|
static boost::program_options::variables_map configuration ;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Get a reference to the configuration structure
|
||||||
|
static boost::program_options::variables_map& getw_configuration(void) ;
|
||||||
|
/// Checks if the key exists in the configuration
|
||||||
|
static bool is_configured(const std::string &key) ;
|
||||||
|
/// Get the string value corresponding to \em key
|
||||||
|
static const std::string& get_string_value(const std::string &key) ;
|
||||||
|
/// Get the int value corresponding to \em key
|
||||||
|
static int get_int_value(const std::string &key) ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif // _OWLPS_POSITIONING_CONFIGURATION_HH_
|
|
@ -1,64 +1,10 @@
|
||||||
#include "owlps-positioning.hh"
|
#include "userinterface.hh"
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
string config_filename = DEFAULT_CONFIG_FILE;
|
UserInterface *ui = new UserInterface(argc, argv) ;
|
||||||
int port, mport;
|
delete ui ; // We don't need it any more
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
/* Options spécifiques à la ligne de commandes */
|
|
||||||
po::options_description generic("Options générales ");
|
|
||||||
generic.add_options()
|
|
||||||
("help,h", "Affichage de l'aide")
|
|
||||||
("config-file,f", po::value<string>(), "Fichier de configuration")
|
|
||||||
("input-topo,T", po::value<string>(), "Input file topology")
|
|
||||||
("input-waypoint,W", po::value<string>(), "Input file waypoint")
|
|
||||||
("input-refpoint,R", po::value<string>(), "Input file reference point")
|
|
||||||
("input-ap,A", po::value<string>(), "Input file accesspoint")
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Options ligne de commandes & fichier de configuration */
|
|
||||||
po::options_description config("Paramètres ");
|
|
||||||
config.add_options()
|
|
||||||
("server.port,l", po::value<int>(&port) -> default_value(9902), "Port d'écoute du serveur")
|
|
||||||
("server.mobile-port,p", po::value<int>(&mport) -> default_value(9903), "Port d'envoi vers le mobile")
|
|
||||||
("db.name,D", po::value<string>(), "Nom de la base de données à utiliser")
|
|
||||||
("db.host,H", po::value<string>(), "Adresse de l'hôte hébergeant la base de données")
|
|
||||||
("db.user,U", po::value<string>(), "Nom de l'utilisateur pour la connexion à la base de données")
|
|
||||||
("db.passwd,P", po::value<string>(), "Mot de passe pour la connexion à la base de données")
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Total des options acceptées en ligne de commandes */
|
|
||||||
po::options_description cmd_line_options("Options acceptées ") ;
|
|
||||||
cmd_line_options.add(generic).add(config) ;
|
|
||||||
|
|
||||||
/* Parcours de la ligne de commandes */
|
|
||||||
po::variables_map vm;
|
|
||||||
po::store(po::parse_command_line(argc, argv, cmd_line_options), vm) ;
|
|
||||||
|
|
||||||
if (vm.count("help")) // L'utilisateur a demandé l'aide
|
|
||||||
{
|
|
||||||
cout << cmd_line_options << endl ;
|
|
||||||
return 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vm.count("config-file")) // L'utilisateur a spécifié un fichier de config
|
|
||||||
config_filename = vm["config-file"].as<string>() ;
|
|
||||||
|
|
||||||
ifstream ifs(config_filename.c_str());
|
|
||||||
if (!ifs.is_open())
|
|
||||||
cerr << "Attention ! Erreur lors de l'ouverture du fichier de configuration « " << config_filename << " » : le fichier n'existe pas ou ne peut être lu.\nUtilisation des valeurs par défaut..." << endl ;
|
|
||||||
else // Parcours du fichier de config
|
|
||||||
po::store(po::parse_config_file(ifs, config), vm) ;
|
|
||||||
|
|
||||||
po::notify(vm);
|
|
||||||
|
|
||||||
Server server(port, mport);
|
|
||||||
|
|
||||||
if (server.init(vm))
|
|
||||||
return 1 ;
|
|
||||||
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef _OWLPS_HH_
|
|
||||||
#define _OWLPS_HH_
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
#include "server.hh"
|
|
||||||
|
|
||||||
//using namespace std ;
|
|
||||||
//namespace po = boost::program_options ;
|
|
||||||
|
|
||||||
#endif // _OWLPS_HH_
|
|
|
@ -7,13 +7,11 @@ using std::tr1::unordered_map ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** Attribute definition *** */
|
/* *** Attribute definitions *** */
|
||||||
|
|
||||||
unordered_map<string, Mobile> Stock::mobiles =
|
unordered_map<string, Mobile> Stock::mobiles ;
|
||||||
unordered_map<string, Mobile>() ;
|
|
||||||
|
|
||||||
unordered_map<string, AccessPoint> Stock::aps =
|
unordered_map<string, AccessPoint> Stock::aps ;
|
||||||
unordered_map<string, AccessPoint>() ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <cxxtest/TestSuite.h>
|
||||||
|
|
||||||
|
#include "configuration.hh"
|
||||||
|
|
||||||
|
class Configuration_test: public CxxTest::TestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void test_accessors(void)
|
||||||
|
{
|
||||||
|
// Non-configured values
|
||||||
|
TS_ASSERT(! Configuration::is_configured("miaou")) ;
|
||||||
|
TS_ASSERT(! Configuration::is_configured("ouaf")) ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Due to the lack of direct variables_map manipulators, it is
|
||||||
|
* hard to manually add values in order to test them.
|
||||||
|
* Some other tests are done in userinterface_test.hh.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
} ;
|
|
@ -0,0 +1,88 @@
|
||||||
|
#include <cxxtest/TestSuite.h>
|
||||||
|
|
||||||
|
#include "userinterface.hh"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
class UserInterface_test: public CxxTest::TestSuite
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string config_file_name ;
|
||||||
|
std::vector<std::string> config_lines ; // Test config file contents
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UserInterface_test(void)
|
||||||
|
{
|
||||||
|
// If we cannot open the file, we want to stop the test
|
||||||
|
CxxTest::setAbortTestOnFail(true) ;
|
||||||
|
|
||||||
|
// Filling name and contents of the config test file
|
||||||
|
config_file_name = "/tmp/UserInterface_test_config_file.csv" ;
|
||||||
|
config_lines.push_back("\n") ;
|
||||||
|
config_lines.push_back("[server]\n") ;
|
||||||
|
config_lines.push_back("\n") ;
|
||||||
|
config_lines.push_back("port = 42\n") ;
|
||||||
|
config_lines.push_back("\n") ;
|
||||||
|
|
||||||
|
// Opening the file
|
||||||
|
std::ofstream config_file ;
|
||||||
|
config_file.open(config_file_name.c_str()) ;
|
||||||
|
if (! config_file)
|
||||||
|
TS_FAIL("Cannot open test config file for creation!") ;
|
||||||
|
|
||||||
|
// Writing contents to the file
|
||||||
|
for (std::vector<std::string>::const_iterator i = config_lines.begin() ;
|
||||||
|
i != config_lines.end() ; ++i)
|
||||||
|
config_file << *i ;
|
||||||
|
|
||||||
|
config_file.close() ;
|
||||||
|
|
||||||
|
// Back to the normal behaviour (i.e. do not abort on fail)
|
||||||
|
CxxTest::setAbortTestOnFail(false) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~UserInterface_test(void)
|
||||||
|
{
|
||||||
|
// Deleting the test config file
|
||||||
|
if (remove(config_file_name.c_str()) == -1)
|
||||||
|
TS_WARN("Cannot remove test config file!") ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static UserInterface_test* createSuite(void)
|
||||||
|
{
|
||||||
|
return new UserInterface_test() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void destroySuite(UserInterface_test *suite)
|
||||||
|
{
|
||||||
|
delete suite ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_constructors(void)
|
||||||
|
{
|
||||||
|
// Note: as --help makes the program exit, we cannot test it.
|
||||||
|
const char *argv[] =
|
||||||
|
{
|
||||||
|
"owlps-positioning", // program name
|
||||||
|
"--config-file",
|
||||||
|
config_file_name.c_str()
|
||||||
|
} ;
|
||||||
|
int argc = 3 ;
|
||||||
|
|
||||||
|
UserInterface ui(argc, const_cast<char**>(argv)) ;
|
||||||
|
|
||||||
|
TS_ASSERT(Configuration::is_configured("server.port")) ;
|
||||||
|
TS_ASSERT(Configuration::is_configured("config-file")) ;
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS(Configuration::get_int_value("server.port"), 42) ;
|
||||||
|
TS_ASSERT_EQUALS(Configuration::get_string_value("config-file"),
|
||||||
|
config_file_name) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} ;
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include "userinterface.hh"
|
||||||
|
#include "configuration.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
namespace po = boost::program_options ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Default value definitions *** */
|
||||||
|
|
||||||
|
#define DEFAULT_CONFIG_FILE_NAME "cfg/owlps-positioning.cfg"
|
||||||
|
#define DEFAULT_LISTENING_PORT 9902
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Constructors *** */
|
||||||
|
|
||||||
|
|
||||||
|
UserInterface::UserInterface(const int argc, char **argv)
|
||||||
|
{
|
||||||
|
cli_argument_count = argc ;
|
||||||
|
cli_argument_values = argv ;
|
||||||
|
config_file_name = DEFAULT_CONFIG_FILE_NAME ;
|
||||||
|
|
||||||
|
cli_options = new po::options_description("General options") ;
|
||||||
|
file_options = new po::options_description("Parameters") ;
|
||||||
|
fill_options() ;
|
||||||
|
|
||||||
|
parse_options() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UserInterface::~UserInterface()
|
||||||
|
{
|
||||||
|
delete cli_options ;
|
||||||
|
delete file_options ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* *** Operations *** */
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::fill_options()
|
||||||
|
{
|
||||||
|
fill_cli_options() ;
|
||||||
|
fill_file_options() ;
|
||||||
|
|
||||||
|
// File options are also accepted on the command line
|
||||||
|
cli_options->add(*file_options) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::fill_cli_options()
|
||||||
|
{
|
||||||
|
cli_options->add_options()
|
||||||
|
("help,h", "Print help")
|
||||||
|
("config-file,f", po::value<string>(),
|
||||||
|
"Alternative configuration file")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::fill_file_options()
|
||||||
|
{
|
||||||
|
file_options->add_options()
|
||||||
|
("server.port,l", po::value<int>()
|
||||||
|
->default_value(DEFAULT_LISTENING_PORT),
|
||||||
|
"Server listening port")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::parse_options()
|
||||||
|
{
|
||||||
|
parse_command_line() ;
|
||||||
|
print_usage_and_exit_if_requested() ;
|
||||||
|
|
||||||
|
// Was the config file name specified on the command line?
|
||||||
|
if (Configuration::is_configured("config-file"))
|
||||||
|
config_file_name = Configuration::get_string_value("config-file") ;
|
||||||
|
|
||||||
|
parse_file() ;
|
||||||
|
|
||||||
|
po::notify(Configuration::getw_configuration()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::parse_command_line() const
|
||||||
|
{
|
||||||
|
po::store(po::parse_command_line(cli_argument_count,
|
||||||
|
cli_argument_values,
|
||||||
|
*cli_options),
|
||||||
|
Configuration::getw_configuration()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::print_usage_and_exit_if_requested() const
|
||||||
|
{
|
||||||
|
if (Configuration::is_configured("help"))
|
||||||
|
{
|
||||||
|
cout << *cli_options ;
|
||||||
|
exit(0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UserInterface::parse_file() const
|
||||||
|
{
|
||||||
|
ifstream config_file(config_file_name.c_str()) ;
|
||||||
|
|
||||||
|
if (! config_file)
|
||||||
|
{
|
||||||
|
cerr
|
||||||
|
<< "Warning! Error opening input configuration file « "
|
||||||
|
<< config_file_name
|
||||||
|
<< " »! Using command line and default values…"
|
||||||
|
<< endl ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
po::store(po::parse_config_file(config_file, *file_options),
|
||||||
|
Configuration::getw_configuration()) ;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef _OWLPS_POSITIONING_USERINTERFACE_HH_
|
||||||
|
#define _OWLPS_POSITIONING_USERINTERFACE_HH_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/program_options/options_description.hpp>
|
||||||
|
|
||||||
|
/// Handles configuration inputs from user
|
||||||
|
class UserInterface
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::string config_file_name ;
|
||||||
|
int cli_argument_count ;
|
||||||
|
char **cli_argument_values ;
|
||||||
|
boost::program_options::options_description *cli_options ;
|
||||||
|
boost::program_options::options_description *file_options ;
|
||||||
|
|
||||||
|
/** @name Operations */
|
||||||
|
//@{
|
||||||
|
/// Fill in all the options
|
||||||
|
void fill_options(void) ;
|
||||||
|
/// Fill in the options accepted on the command line
|
||||||
|
void fill_cli_options(void) ;
|
||||||
|
/// \brief Fill in the options accepted on the command line and in
|
||||||
|
/// the configuration file
|
||||||
|
void fill_file_options(void) ;
|
||||||
|
/// Parse all the configuration inputs and updates Configuration
|
||||||
|
void parse_options(void) ;
|
||||||
|
void parse_command_line(void) const ;
|
||||||
|
void parse_file(void) const ;
|
||||||
|
/// If help was requested by user, displays accepted options and exit
|
||||||
|
void print_usage_and_exit_if_requested(void) const ;
|
||||||
|
//@}
|
||||||
|
|
||||||
|
public:
|
||||||
|
UserInterface(const int argc, char **argv) ;
|
||||||
|
|
||||||
|
~UserInterface(void) ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif // _OWLPS_POSITIONING_USERINTERFACE_HH_
|
Loading…
Reference in New Issue