#include "userinterface.hh" #include "configuration.hh" #include #include #include #include using namespace std ; namespace po = boost::program_options ; /* *** Default value definitions *** */ #define DEFAULT_CONFIG_FILE_NAME \ "/usr/local/etc/owlps/owlps-positioning.cfg" /* *** Constructors *** */ /** * \em argc and \em argv are (normally) the ones passed to the main() * function. * @param argc Number of arguments passed to the program. * @param argv Values of the arguments. */ UserInterface::UserInterface(const int argc, char **argv) { assert(argv) ; cli_argument_values = argv ; cli_argument_count = argc ; try { cli_options = new po::options_description("General options") ; file_options = new po::options_description("Parameters") ; } catch (bad_alloc e) { throw ; } 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.") ("version,V", "Print version information.") ("config-file,f", po::value() ->default_value(DEFAULT_CONFIG_FILE_NAME), "Alternative configuration file.") ; // End of options } void UserInterface::fill_file_options() { fill_data_input_options() ; fill_input_options() ; fill_log_options() ; fill_positioning_options() ; fill_output_options() ; fill_misc_options() ; } void UserInterface::fill_data_input_options() { po::options_description options("Data input options") ; options.add_options() ("data-input.ap-medium", po::value< vector >() ->composing(), "Medium from which access points are read. You can specify this \ option more than once. Allowed: CSV.") ("data-input.ap-csv-file", po::value(), "CSV file to use for access points input (when \ data-input.ap-medium = CSV).") ("data-input.topology-medium,T", po::value< vector >() ->composing(), "Medium from which topology (buildings, areas and waypoints) is \ read. You can specify this option more than once. Allowed: CSV.") ("data-input.areas-csv-file,A", po::value(), "CSV file to use for topology input (when \ data-input.topology-medium = CSV).") ("data-input.waypoints-csv-file,W", po::value(), "CSV file to use for waypoints input (when \ data-input.topology-medium = CSV).") ("data-input.reference-points-medium,R", po::value< vector >() ->composing(), "Medium from which reference points are read. You can specify this \ option more than once. Allowed: CSV.") ("data-input.reference-points-csv-file", po::value(), "CSV file to use for reference points input (when \ data-input.reference-points-medium = CSV).") ; file_options->add(options) ; } void UserInterface::fill_input_options() { po::options_description options("Input options") ; options.add_options() ("input.medium,I", po::value(), "Medium from which requests are read. Allowed: CSV, UDP.") ("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), "Port on which the UDP socket listens (when input.medium = UDP).") ; file_options->add(options) ; } void UserInterface::fill_log_options() { po::options_description options("Log options") ; options.add_options() ("log.medium,L", po::value< vector >()->composing(), "Medium to which the requests will be logged. You can specify \ this option more than once. Allowed: none, CSV. The `none` value \ completely disables logging.") ("log.csv-file", po::value(), "CSV file to use for logging (when log.medium = CSV).") ; file_options->add(options) ; } void UserInterface::fill_positioning_options() { po::options_description options("Positioning options") ; options.add_options() ("positioning.algorithm,a", po::value< vector >()->composing(), "Algorithms used to compute positions. You can specify \ this option more than once (but at least once). Allowed: Real, FBCM, \ FRBHMBasic, InterlinkNetworks, RADAR.") ("positioning.minmax-start", po::value(), "Coordinates of the start point of the MinMax multilateration \ method (string format: \"X;Y;Z\").") ("positioning.minmax-stop", po::value(), "Coordinates of the stop point of the MinMax multilateration \ method (string format: \"X;Y;Z\").") ; file_options->add(options) ; } void UserInterface::fill_output_options() { po::options_description options("Output options") ; options.add_options() ("output.medium,O", po::value< vector >()->composing(), "Medium to which the results will be wrote. You can specify \ this option more than once. Allowed: Terminal, CSV, UDP. \ If this option is absent, results will be printed on the terminal.") ("output.csv-file", po::value(), "CSV file to use for output (when output.medium = CSV).") ("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), "Port on which the UDP data is sent (when output.medium = UDP).") ; file_options->add(options) ; } void UserInterface::fill_misc_options() { po::options_description options("Miscellaneous options") ; options.add_options() ("flush-output-files", po::value()->default_value(true), "Flush output text files after each line.") ; file_options->add(options) ; } void UserInterface::parse_options() { parse_command_line() ; print_information_and_exit_if_requested() ; 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_information_and_exit_if_requested() const { bool exit_program = false ; // Print version if requested if (Configuration::is_configured("version")) { cout << "This is OwlPS Positioning, part of the Open Wireless" << " Positioning System project.\nVersion: " << #ifdef OWLPS_VERSION OWLPS_VERSION #else // OWLPS_VERSION "unknown version" #endif // OWLPS_VERSION << ".\n" ; exit_program = true ; } // Print usage if requested if (Configuration::is_configured("help")) { cout << *cli_options ; exit_program = true ; } if (exit_program) exit(0) ; } void UserInterface::parse_file() const { string config_file_name = Configuration::string_value("config-file") ; 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()) ; }