#include "writeindb.hh" template 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 explode(const string &input, const char &sep) { vector 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 extractReferencePointInfoFromBuffer(const string &buffer_in) { unsigned int i = 0; string tmp_field; vector 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 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(infos[0]); y = from_string(infos[1]); z = from_string(infos[2]); tmp_point.setX(x); tmp_point.setY(y); tmp_point.setZ(z); direction = from_string(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(infos[i+1])); i++; } } } } input_file.close(); infos.clear() ; } void WriteInDb::makeApListFromFile(const string &filename) { ifstream input_file; string buffer; vector 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(ap_infos[1]), from_string(ap_infos[2]), from_string(ap_infos[3])); tmp_ap.setFrequency(from_string(ap_infos[4])); tmp_ap.setAntennaGain(from_string(ap_infos[5])); tmp_ap.setOutputPower(from_string(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 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(infos[1]), from_string(infos[3]), from_string(infos[2]), from_string(infos[4]), from_string(infos[5]), from_string(infos[6])) ; infos.clear() ; } } input_file.close() ; } void WriteInDb::makeWaypointListFromFile(const string &filename) { ifstream input_file ; string buffer; vector 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(infos[0]), from_string(infos[1]), from_string(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(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(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 m_list; vector 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(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(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::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 &point_list, const Point &p) const { return (pointIndex(point_list, p) != -1); } inline int WriteInDb::pointIndex(const vector &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(), "\t: Input file topology") ("input-waypoint,W", po::value(), "\t: Input file waypoint") ("input-refpoint,R", po::value(), "\t: Input file reference point") ("input-ap,A", po::value(), "\t: Input file accesspoint") ; conf.add_options() ("Server.port", po::value() -> default_value(9902), "\t: Port du serveur") ("Server.mobile-port", po::value() -> default_value(9903), "\t: Port d'envoi vers le mobile") ("BDD.name", po::value(), "\t: Nom de la BdD") ("BDD.hostaddr", po::value(), "\t: Adresse de l'hôte de la BdD") ("BDD.user", po::value(), "\t: Nom de l'utilisateur de la BdD") ("BDD.passwd", po::value(), "\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() << "' "; oss << "dbname = '" << vm["BDD.name"].as() << "' "; oss << "user = '" << vm["BDD.user"].as() << "' "; oss << "password = '"<< vm["BDD.passwd"].as() << "'"; 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()); w.writeAccessPointToDb(conn); } if (vm.count("input-topo")) { w.makeTopologyFromFile(vm["input-topo"].as()); w.writeTopologyToDb(conn); } if (vm.count("input-waypoint")) { w.makeWaypointListFromFile(vm["input-waypoint"].as()); w.writeWaypointToDb(conn); } if (vm.count("input-refpoint")) { w.makeReferencePointListFromFile(vm["input-refpoint"].as(), true); w.writeReferencePointToDb(conn); } PQfinish(conn); return 0; }