/* * This file is part of the Owl Positioning System (OwlPS). * OwlPS is a project of the University of Franche-Comte * (Université de Franche-Comté), France. * * Copyright © Université de Franche-Comté 2007-2012. * * Corresponding author: Matteo Cypriani * *********************************************************************** * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL: * http://www.cecill.info * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided * only with a limited warranty and the software's authors, the holder * of the economic rights, and the successive licensors have only * limited liability. * * In this respect, the user's attention is drawn to the risks * associated with loading, using, modifying and/or developing or * reproducing the software by the user in light of its specific status * of free software, that may mean that it is complicated to manipulate, * and that also therefore means that it is reserved for developers and * experienced professionals having in-depth computer knowledge. Users * are therefore encouraged to load and test the software's suitability * as regards their requirements in conditions enabling the security of * their systems and/or data to be ensured and, more generally, to use * and operate it in the same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. * *********************************************************************** */ #include "request.hh" #include "calibrationrequest.hh" #include "referencepoint.hh" #include "mobile.hh" #include using namespace std ; using std::tr1::unordered_map ; /* *** Constructors *** */ Request::Request( const Mobile *_mobile, const Timestamp &_time_sent, const std::tr1::unordered_map &_measurements ): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(const_cast(_mobile)), time_sent(_time_sent), measurements(_measurements), real_position(NULL) { received_now() ; } Request::Request(const std::tr1::unordered_map &_measurements): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(NULL), measurements(_measurements), real_position(NULL) { received_now() ; } Request::Request( const Timestamp &_time_sent, const std::tr1::unordered_map &_measurements ): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(NULL), time_sent(_time_sent), measurements(_measurements), real_position(NULL) { received_now() ; } Request::Request(const Request &source): type(source.type), nb_packets(source.nb_packets), mobile(source.mobile), time_sent(source.time_sent), time_received(source.time_received), measurements(source.measurements), real_position(NULL) { if (source.real_position) real_position = new Point3D(*source.real_position) ; } /** * Note that the value pointed by #mobile is not deleted. */ Request::~Request() { measurements.clear() ; } /* *** Read accessors *** */ /** * @param mac_receiver The MAC address of the receiver AP. * @returns A pointer on the found measurement, or NULL if no * measurement was made by this AP. */ const Measurement* Request::get_measurement(const string &mac_receiver) const { unordered_map::const_iterator m = measurements.find(mac_receiver) ; if (m != measurements.end()) return &m->second ; return NULL ; } /* *** Write accessors *** */ inline void Request::clear_real_position() { if (real_position) { delete real_position ; real_position = NULL ; } } void Request::set_real_position(const Point3D &_real_position) { if (real_position) *real_position = _real_position ; else real_position = new Point3D(_real_position) ; } /** * - #nb_packets is set to 1 (this is the default value when * constructing a Request). * - #mobile is NULLified, but the value it pointed to is not deleted. * - The fields of #time_sent and #time_received are initialised to 0. * - #measurements is cleared. */ void Request::clear() { type = OWL_REQUEST_UNDEFINED ; nb_packets = 1 ; mobile = NULL ; time_sent.clear() ; time_received.clear() ; measurements.clear() ; clear_real_position() ; } /* *** Operations *** */ float Request::similarity(const Request &source) const { unordered_map source_measurements(source.measurements) ; unordered_map my_measurements(measurements) ; PosUtil::complete_with_dummy_measurements( my_measurements, source_measurements) ; return PosUtil::similarity( my_measurements, source_measurements) ; } /* *** Operators *** */ Request& Request::operator=(const Request &source) { if (this == &source) return *this ; type = source.type ; nb_packets = source.nb_packets ; mobile = source.mobile ; time_sent = source.time_sent ; time_received = source.time_received ; measurements = source.measurements ; clear_real_position() ; if (source.real_position) real_position = new Point3D(*source.real_position) ; return *this ; } bool Request::operator==(const Request &source) const { if (this == &source) return true ; bool real_position_equal = real_position && source.real_position && *real_position == *source.real_position ; return real_position_equal && type == source.type && nb_packets == source.nb_packets && mobile == source.mobile && time_sent == source.time_sent && time_received == source.time_received && measurements == source.measurements ; } const string Request::to_csv() const { ostringstream csv_line ; if (mobile != NULL) csv_line << mobile->get_mac_addr() ; csv_line << ';' << static_cast(type) << ';' << nb_packets << ';' << time_sent << ';' ; const CalibrationRequest *calibration_request = dynamic_cast(this) ; if (calibration_request == NULL) csv_line << "0;0;0;0" ; else { csv_line << calibration_request->get_reference_point()->get_x() << ';' << calibration_request->get_reference_point()->get_y() << ';' << calibration_request->get_reference_point()->get_z() << ';' << static_cast(calibration_request->get_direction()) ; } for (unordered_map::const_iterator i = measurements.begin() ; i != measurements.end() ; ++i) csv_line << ';' << i->second.to_csv() ; return csv_line.str() ; } ostream& operator<<(ostream &os, const Request &r) { // Timestamp os << "At " << r.time_sent << " (received at " << r.time_received << "; " ; if (r.real_position) os << " Real coordinates : " << *r.real_position << "; " ; // MAC address os << "Type: " << static_cast(r.type) << ", Number of packets sent: " << r.nb_packets << ", Mobile: " << (r.mobile != NULL ? r.mobile->get_mac_addr() : "Unknown_Mobile") << ":" ; // List of Measurements if (r.measurements.empty()) os << " No values" ; else for (unordered_map::const_iterator i = r.measurements.begin() ; i != r.measurements.end() ; ++i) os << '\n' << i->first << ": " << i->second ; return os ; } /** * The Mobile MAC address and the Timestamp are sufficient to identify * uniquely a Request. */ size_t hash_value(const Request &source) { size_t seed = 0 ; boost::hash_combine(seed, source.type) ; boost::hash_combine(seed, source.nb_packets) ; boost::hash_combine(seed, source.time_sent) ; boost::hash_combine(seed, source.time_received) ; if (source.mobile) boost::hash_combine(seed, source.mobile->get_mac_addr()) ; if (source.real_position) boost::hash_combine(seed, source.real_position) ; return seed ; }