diff --git a/owlps-positioning/Makefile b/owlps-positioning/Makefile index 34a30fb..dd95255 100644 --- a/owlps-positioning/Makefile +++ b/owlps-positioning/Makefile @@ -61,6 +61,7 @@ OBJ_LIST = \ configuration.o \ userinterface.o \ inputdatareader.o \ + accesspointsreadercsv.o \ topologyreadercsv.o \ textfilereader.o \ csvfilereader.o \ @@ -115,6 +116,8 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc $(SRC_DIR)/%.hh $(LD) $(LDFLAGS) -o $@ $^ # Dependencies +$(OBJ_DIR)/posutil.o: \ + $(OBJ_DIR)/posexcept.o $(OBJ_DIR)/owlps-positioning.o: \ $(OBJ_DIR)/posexcept.o $(OBJ_DIR)/owlps-positioning.o: \ @@ -125,9 +128,14 @@ $(OBJ_DIR)/owlps-positioning.o: \ $(OBJ_DIR)/userinterface.o: \ $(OBJ_DIR)/configuration.o $(OBJ_DIR)/inputdatareader.o: \ + $(OBJ_DIR)/accesspointsreadercsv.o \ $(OBJ_DIR)/topologyreadercsv.o \ $(OBJ_DIR)/configuration.o \ $(OBJ_DIR)/posexcept.o +$(OBJ_DIR)/accesspointsreadercsv.o: \ + $(OBJ_DIR)/csvfilereader.o \ + $(OBJ_DIR)/accesspoint.o \ + $(OBJ_DIR)/stock.o $(OBJ_DIR)/topologyreadercsv.o: \ $(OBJ_DIR)/csvfilereader.o \ $(OBJ_DIR)/area.o \ @@ -147,6 +155,7 @@ $(OBJ_DIR)/wifidevice.o: \ $(OBJ_DIR)/posutil.o $(OBJ_DIR)/accesspoint.o: \ $(OBJ_DIR)/wifidevice.o \ + $(OBJ_DIR)/posutil.o \ $(OBJ_DIR)/point3d.o $(OBJ_DIR)/mobile.o: \ $(OBJ_DIR)/wifidevice.o diff --git a/owlps-positioning/src/accesspointsreadercsv.cc b/owlps-positioning/src/accesspointsreadercsv.cc new file mode 100644 index 0000000..b6c7508 --- /dev/null +++ b/owlps-positioning/src/accesspointsreadercsv.cc @@ -0,0 +1,57 @@ +#include "accesspointsreadercsv.hh" +#include "point3d.hh" +#include "stock.hh" +#include "posexcept.hh" + +using namespace std ; + + + +/* *** Constructors *** */ + + +AccessPointsReaderCSV::AccessPointsReaderCSV(const string &file_name): + file(file_name) +{ + read_access_points() ; +} + + + +/* *** Operations *** */ + + +void AccessPointsReaderCSV::read_access_points() +{ + while (file.next_line()) + process_access_point_line() ; +} + + +void AccessPointsReaderCSV::process_access_point_line() +{ + string mac ; + if (! file.read_field(mac)) + throw malformed_input_data("Cannot read access point MAC address!") ; + + Point3D coord ; + if (! file.read_point3d(coord)) + throw malformed_input_data("Cannot read access point coordinates!") ; + + long frequency ; + if (! file.read_field(frequency)) + throw malformed_input_data("Cannot read access point frequency!") ; + + float gain ; + if (! file.read_field(gain)) + throw malformed_input_data("Cannot read access point gain!") ; + + float power ; + if (! file.read_field(power)) + throw malformed_input_data("Cannot read access point power!") ; + + string ip("") ; + + AccessPoint ap(coord, ip, mac, gain, power, frequency) ; + Stock::find_create_ap(ap) ; +} diff --git a/owlps-positioning/src/accesspointsreadercsv.hh b/owlps-positioning/src/accesspointsreadercsv.hh new file mode 100644 index 0000000..97d8191 --- /dev/null +++ b/owlps-positioning/src/accesspointsreadercsv.hh @@ -0,0 +1,29 @@ +#ifndef _OWLPS_POSITIONING_ACCESSPOINTSREADERCSV_HH_ +#define _OWLPS_POSITIONING_ACCESSPOINTSREADERCSV_HH_ + +class Point3D ; + +#include "csvfilereader.hh" + +#include + +/// Reads and registers to the Stock AccessPoint list from CSV files +/** + * CSV format for access points is: + * MAC;X;Y;Z;Frequency_Hz;Antenna_gain_dBi;Trx_power_dBm + */ +class AccessPointsReaderCSV +{ +protected: + CSVFileReader file ; + + void read_access_points(void) ; + void process_access_point_line(void) ; + +public: + AccessPointsReaderCSV(const std::string &file_name) ; + + ~AccessPointsReaderCSV(void) {} +} ; + +#endif // _OWLPS_POSITIONING_ACCESSPOINTSREADERCSV_HH_ diff --git a/owlps-positioning/src/inputdatareader.cc b/owlps-positioning/src/inputdatareader.cc index f2ab587..4ca8062 100644 --- a/owlps-positioning/src/inputdatareader.cc +++ b/owlps-positioning/src/inputdatareader.cc @@ -1,4 +1,5 @@ #include "inputdatareader.hh" +#include "accesspointsreadercsv.hh" #include "topologyreadercsv.hh" #include "inputcsv.hh" #include "calibrationrequest.hh" @@ -17,6 +18,7 @@ using namespace std ; InputDataReader::InputDataReader() { + read_access_points() ; read_topology() ; read_reference_points() ; } @@ -33,6 +35,48 @@ InputDataReader::~InputDataReader() +/* *** Access points *** */ + + +void InputDataReader::read_access_points() +{ + if (! Configuration::is_configured("data-input.ap-medium")) + return ; + + initialise_access_points_media() ; +} + + +void InputDataReader::initialise_access_points_media() +{ + const vector &media_names = + Configuration::string_vector_value("data-input.ap-medium") ; + + for (vector::const_iterator i = media_names.begin() ; + i != media_names.end() ; ++i) + { + if (*i == "CSV") + initialise_access_points_csv() ; + + else + throw bad_configuration( + "Access points input medium type unknown « "+ *i +" »") ; + } +} + + +void InputDataReader::initialise_access_points_csv() +{ + if (! Configuration::is_configured("data-input.ap-csv-file")) + throw missing_configuration( + "No input CSV file specified for access points") ; + + AccessPointsReaderCSV( + Configuration::string_value("data-input.ap-csv-file")) ; +} + + + /* *** Topology *** */ @@ -58,8 +102,7 @@ void InputDataReader::initialise_topology_media() else throw bad_configuration( - "The specified topology input medium « "+ *i + - " » is unknown!") ; + "Topology input medium type unknown « "+ *i +" »") ; } } diff --git a/owlps-positioning/src/inputdatareader.hh b/owlps-positioning/src/inputdatareader.hh index e316e2a..21023f8 100644 --- a/owlps-positioning/src/inputdatareader.hh +++ b/owlps-positioning/src/inputdatareader.hh @@ -12,6 +12,10 @@ class InputDataReader protected: std::vector reference_points_media ; + void read_access_points(void) ; + void initialise_access_points_media(void) ; + void initialise_access_points_csv(void) ; + void read_topology(void) ; void initialise_topology_media(void) ; void initialise_topology_csv(void) ; diff --git a/owlps-positioning/src/stock.cc b/owlps-positioning/src/stock.cc index 2fa780e..7fd735e 100644 --- a/owlps-positioning/src/stock.cc +++ b/owlps-positioning/src/stock.cc @@ -181,6 +181,21 @@ const AccessPoint& Stock::find_create_ap(const string &mac) } +/** + * If the AccessPoint already exists, it is replaced by the \em source. + */ +const AccessPoint& Stock::find_create_ap(const AccessPoint &source) +{ + const string &mac = source.get_mac_addr() ; + unordered_map::const_iterator i = aps.find(mac) ; + if (i != aps.end()) + return i->second ; + + aps[mac] = source ; + return aps[mac] ; +} + + void Stock::update_all_friis_indexes() { for (unordered_map::iterator ap = aps.begin() ; diff --git a/owlps-positioning/src/stock.hh b/owlps-positioning/src/stock.hh index e9884f9..8da7ab4 100644 --- a/owlps-positioning/src/stock.hh +++ b/owlps-positioning/src/stock.hh @@ -75,6 +75,9 @@ public: /// Read the AccessPoint corresponding to a given MAC address static const AccessPoint& get_ap(const std::string &mac) ; /// Look for an AccessPoint and create it if it does not exist + static const AccessPoint& find_create_ap(const AccessPoint &source) ; + /// \brief Look for an AccessPoint given its MAC address and create it + /// if it does not exist static const AccessPoint& find_create_ap(const std::string &mac) ; /// Get a reference to the AccessPoint corresponding to a given MAC address static AccessPoint& getw_ap(const std::string &mac) ; diff --git a/owlps-positioning/src/userinterface.cc b/owlps-positioning/src/userinterface.cc index a4d3108..f583bd2 100644 --- a/owlps-positioning/src/userinterface.cc +++ b/owlps-positioning/src/userinterface.cc @@ -109,6 +109,13 @@ 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 \