615 lines
16 KiB
C++
615 lines
16 KiB
C++
#include "writeindb.hh"
|
|
|
|
template <class T>
|
|
inline T from_string(const string &s)
|
|
{
|
|
|
|
T t;
|
|
istringstream iss(s);
|
|
|
|
iss >> t;
|
|
|
|
return t;
|
|
}
|
|
|
|
inline string stringToLower(string strToConvert)
|
|
{
|
|
|
|
for (unsigned int i=0; i < strToConvert.length(); i++)
|
|
{
|
|
strToConvert[i] = tolower(strToConvert[i]);
|
|
}
|
|
|
|
return strToConvert;
|
|
}
|
|
|
|
inline 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;
|
|
}
|
|
|
|
inline vector<string> extractReferencePointInfoFromBuffer(const string &buffer_in)
|
|
{
|
|
unsigned int i = 0;
|
|
string tmp_field;
|
|
vector<string> ret;
|
|
|
|
while (buffer_in[i] != ';')
|
|
{
|
|
tmp_field.push_back(buffer_in[i]);
|
|
i++;
|
|
}
|
|
ret.push_back(tmp_field);
|
|
tmp_field.clear();
|
|
i++; // go after the ';'
|
|
|
|
while (buffer_in[i] != ';')
|
|
{
|
|
tmp_field.push_back(buffer_in[i]);
|
|
i++;
|
|
}
|
|
ret.push_back(tmp_field);
|
|
tmp_field.clear();
|
|
i++;
|
|
|
|
while (buffer_in[i] != ';')
|
|
{
|
|
tmp_field.push_back(buffer_in[i]);
|
|
i++;
|
|
}
|
|
ret.push_back(tmp_field);
|
|
tmp_field.clear();
|
|
i++;
|
|
|
|
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 ret;
|
|
}
|
|
|
|
void WriteInDb::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 WriteInDb::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 WriteInDb::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 WriteInDb::makeWaypointListFromFile(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)
|
|
{
|
|
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]));
|
|
waypoint_list.push_back(tmp_pt);
|
|
|
|
infos.clear() ;
|
|
}
|
|
}
|
|
input_file.close(); // Lecture du fichier terminée
|
|
}
|
|
|
|
void WriteInDb::writeAccessPointToDb(PGconn *conn)
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
ostringstream oss;
|
|
string buf;
|
|
bool exist = false;
|
|
string addr_files;
|
|
|
|
buf = "SELECT * FROM ap;";
|
|
res = PQexec(conn, buf.c_str());
|
|
|
|
for (unsigned int i = 0; i < access_point_list.size(); i++)
|
|
{
|
|
addr_files = stringToLower(access_point_list[i].getApAddr());
|
|
if (PQresultStatus(res) == PGRES_TUPLES_OK)
|
|
{
|
|
int nbRes = PQntuples(res);
|
|
for (int j = 0; j < nbRes; j++)
|
|
{
|
|
if (addr_files == PQgetvalue(res, i, 1))
|
|
exist = true;
|
|
}
|
|
}
|
|
|
|
if (exist)
|
|
{
|
|
oss << "UPDATE ap SET x = '" << access_point_list[i].getCoordinates().getX() << "','";
|
|
oss << "y = '" << access_point_list[i].getCoordinates().getY() << "','";
|
|
oss << "z = '" << access_point_list[i].getCoordinates().getZ() << "','";
|
|
oss << "friis_index = '" << access_point_list[i].getFriisIndex() << "','";
|
|
oss << "freq = '" << access_point_list[i].getFrequency() << "','";
|
|
oss << "antenna_gain = '" << access_point_list[i].getAntennaGain() << "','";
|
|
oss << "output_power = '" << access_point_list[i].getOutputPower();
|
|
oss << " WHERE ap_addr = '" << addr_files << ";";
|
|
}
|
|
else
|
|
{
|
|
oss << "INSERT INTO ap(ap_addr,x,y,z,friis_index,freq,antenna_gain,output_power) VALUES('";
|
|
oss << addr_files << "','";
|
|
oss << access_point_list[i].getCoordinates().getX() << "','";
|
|
oss << access_point_list[i].getCoordinates().getY() << "','";
|
|
oss << access_point_list[i].getCoordinates().getZ() << "','";
|
|
oss << access_point_list[i].getFriisIndex() << "','";
|
|
oss << access_point_list[i].getFrequency() << "','";
|
|
oss << access_point_list[i].getAntennaGain() << "','";
|
|
oss << access_point_list[i].getOutputPower() << "');";
|
|
}
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
exist = false;
|
|
}
|
|
PQclear(res);
|
|
}
|
|
|
|
void WriteInDb::writeWaypointToDb(PGconn *conn)
|
|
{
|
|
ostringstream oss;
|
|
string buf;
|
|
|
|
for (unsigned int i = 0; i < waypoint_list.size(); i++)
|
|
{
|
|
oss << "INSERT INTO waypoint VALUES('";
|
|
oss << waypoint_list[i].getX() << "','";
|
|
oss << waypoint_list[i].getY() << "','";
|
|
oss << waypoint_list[i].getZ() << "');";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
}
|
|
}
|
|
|
|
int WriteInDb::writePointToDb(PGconn *conn, Point p)
|
|
{
|
|
|
|
ostringstream oss;
|
|
string buf;
|
|
int id_point = -1;
|
|
|
|
PGresult *res;
|
|
|
|
oss << "SELECT * FROM ref_point ";
|
|
oss << "WHERE x = " << p.getX();
|
|
oss << " AND y = " << p.getY();
|
|
oss << " AND z = " << p.getZ();
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
res = PQexec(conn, buf.c_str());
|
|
if (PQntuples(res) == 0)
|
|
{
|
|
PQclear(res);
|
|
buf = "SELECT * FROM ref_point;";
|
|
res = PQexec(conn, buf.c_str());
|
|
id_point = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)) + 1: 1;
|
|
|
|
oss << "INSERT INTO ref_point(id_ref_point,x,y,z,direction) VALUES('";
|
|
oss << id_point << "','";
|
|
oss << p.getX() << "','";
|
|
oss << p.getY() << "','";
|
|
oss << p.getZ() << "','";
|
|
oss << " " << "');";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
}
|
|
else
|
|
{
|
|
id_point = from_string<int>(PQgetvalue(res, 0, 0));
|
|
}
|
|
|
|
return id_point;
|
|
}
|
|
|
|
void WriteInDb::writeReferencePointToDb(PGconn *conn)
|
|
{
|
|
|
|
ostringstream oss;
|
|
string buf;
|
|
PGresult *res;
|
|
|
|
struct timeval current_time ;
|
|
int id_point, id_ap, id_request;
|
|
|
|
vector<Measurement> m_list;
|
|
vector<int> ss_list;
|
|
|
|
for (unsigned int i = 0; i < reference_point_list.size(); i++)
|
|
{
|
|
buf = "SELECT * FROM ref_request;";
|
|
res = PQexec(conn, buf.c_str());
|
|
id_request = (PQntuples(res) != 0)? from_string<int>(PQgetvalue(res, PQntuples(res) - 1, 0)) + 1: 1;
|
|
|
|
id_point = writePointToDb(conn, reference_point_list[i].getCoordinates());
|
|
oss << "INSERT INTO ref_request(id_ref_request, id_ref_point) VALUES('";
|
|
oss << id_request << "','";
|
|
oss << id_point << "');";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
|
|
m_list = reference_point_list[i].getMeasurementList();
|
|
for (unsigned int j = 0; j < m_list.size(); j++)
|
|
{
|
|
oss << "SELECT id_ap FROM ap WHERE ap_addr = '";
|
|
oss << stringToLower(m_list[j].getMacAddr()) << "';";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQclear(res);
|
|
res = PQexec(conn, buf.c_str());
|
|
id_ap = from_string<int>(PQgetvalue(res, 0, 0));
|
|
|
|
ss_list = m_list[j].getSsList();
|
|
for (unsigned int k = 0; k < ss_list.size(); k++)
|
|
{
|
|
oss << "INSERT INTO ref_packet(power, id_ap, id_ref_request) VALUES('";
|
|
oss << ss_list[k] << "','";
|
|
oss << id_ap << "','";
|
|
oss << id_request << "');";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
}
|
|
}
|
|
}
|
|
PQclear(res);
|
|
}
|
|
|
|
void WriteInDb::writeTopologyToDb(PGconn *conn)
|
|
{
|
|
|
|
ostringstream oss;
|
|
string buf;
|
|
PGresult *res;
|
|
|
|
bool exist = false;
|
|
|
|
buf = "SELECT * from area;";
|
|
res = PQexec(conn, buf.c_str());
|
|
|
|
for (map<string, Area>::iterator it = area_list.begin() ; it != area_list.end() ; it++)
|
|
{
|
|
if (PQresultStatus(res) == PGRES_TUPLES_OK)
|
|
{
|
|
int nbRes = PQntuples(res);
|
|
for (int j = 0; j < nbRes; j++)
|
|
{
|
|
if (it -> second.getName() == PQgetvalue(res, j, 1))
|
|
exist = true;
|
|
}
|
|
}
|
|
|
|
if (!exist)
|
|
{
|
|
oss << "INSERT INTO area(name_area,x_min,y_min,z_min,x_max,y_max,z_max) VALUES ('";
|
|
oss << it -> second.getName() << "','";
|
|
oss << it -> second.getXmin() << "','";
|
|
oss << it -> second.getYmin() << "','";
|
|
oss << it -> second.getZmin() << "','";
|
|
oss << it -> second.getXmax() << "','";
|
|
oss << it -> second.getYmax() << "','";
|
|
oss << it -> second.getZmax() << "');";
|
|
|
|
buf = oss.str();
|
|
oss.str("");
|
|
|
|
PQexec(conn, buf.c_str());
|
|
}
|
|
|
|
exist = false;
|
|
}
|
|
|
|
PQclear(res);
|
|
}
|
|
|
|
inline bool WriteInDb::pointExists(const vector<ReferencePoint> &point_list, const Point &p) const
|
|
{
|
|
return (pointIndex(point_list, p) != -1);
|
|
}
|
|
|
|
inline int WriteInDb::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;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
|
|
WriteInDb w;
|
|
|
|
po::options_description conf("Configuration Positioner");
|
|
po::options_description desc("Options");
|
|
po::variables_map vm;
|
|
|
|
ifstream ifs("bdd.cfg");
|
|
|
|
desc.add_options()
|
|
("help", "\t: Affichage de l'aide")
|
|
("input-topo,T", po::value<string>(), "\t: Input file topology")
|
|
("input-waypoint,W", po::value<string>(), "\t: Input file waypoint")
|
|
("input-refpoint,R", po::value<string>(), "\t: Input file reference point")
|
|
("input-ap,A", po::value<string>(), "\t: Input file accesspoint")
|
|
;
|
|
conf.add_options()
|
|
("Server.port", po::value<int>() -> default_value(9902), "\t: Port du serveur")
|
|
("Server.mobile-port", po::value<int>() -> default_value(9903), "\t: Port d'envoi vers le mobile")
|
|
("BDD.name", po::value<string>(), "\t: Nom de la BdD")
|
|
("BDD.hostaddr", po::value<string>(), "\t: Adresse de l'hôte de la BdD")
|
|
("BDD.user", po::value<string>(), "\t: Nom de l'utilisateur de la BdD")
|
|
("BDD.passwd", po::value<string>(), "\t: Mot de passe de la BdD")
|
|
;
|
|
|
|
po::store(po::parse_config_file(ifs, conf), vm);
|
|
po::store(po::parse_command_line(argc, argv, desc), vm);
|
|
po::notify(vm);
|
|
|
|
if (vm.count("help"))
|
|
{
|
|
cout << desc << endl;
|
|
return 0;
|
|
}
|
|
|
|
ostringstream oss;
|
|
string buf;
|
|
|
|
oss << "hostaddr = '" << vm["BDD.hostaddr"].as<string>() << "' ";
|
|
oss << "dbname = '" << vm["BDD.name"].as<string>() << "' ";
|
|
oss << "user = '" << vm["BDD.user"].as<string>() << "' ";
|
|
oss << "password = '"<< vm["BDD.passwd"].as<string>() << "'";
|
|
buf = oss.str();
|
|
|
|
const char *conninfo = buf.c_str();
|
|
PGconn *conn;
|
|
|
|
conn = PQconnectdb(conninfo);
|
|
|
|
if (PQstatus(conn) != CONNECTION_OK)
|
|
{
|
|
cout << "Connection à la base de donnée échouée: " << PQerrorMessage(conn) << endl;
|
|
PQfinish(conn);
|
|
return 1;
|
|
}
|
|
|
|
if (vm.count("input-ap"))
|
|
{
|
|
w.makeApListFromFile(vm["input-ap"].as<string>());
|
|
w.writeAccessPointToDb(conn);
|
|
}
|
|
|
|
if (vm.count("input-topo"))
|
|
{
|
|
w.makeTopologyFromFile(vm["input-topo"].as<string>());
|
|
w.writeTopologyToDb(conn);
|
|
}
|
|
|
|
if (vm.count("input-waypoint"))
|
|
{
|
|
w.makeWaypointListFromFile(vm["input-waypoint"].as<string>());
|
|
w.writeWaypointToDb(conn);
|
|
}
|
|
|
|
if (vm.count("input-refpoint"))
|
|
{
|
|
w.makeReferencePointListFromFile(vm["input-refpoint"].as<string>(), true);
|
|
w.writeReferencePointToDb(conn);
|
|
}
|
|
|
|
PQfinish(conn);
|
|
return 0;
|
|
}
|