/* * This file is part of the Owl Positioning System (OwlPS) project. * It is subject to the copyright notice and license terms in the * COPYRIGHT.t2t file found in the top-level directory of this * distribution and at * https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t * No part of the OwlPS Project, including this file, may be copied, * modified, propagated, or distributed except according to the terms * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be * distributed along with this file, either separately or by replacing * this notice by the COPYRIGHT.t2t file's contents. */ #include "request.hh" #include "calibrationrequest.hh" #include "referencepoint.hh" #include using namespace std ; /* *** Constructors *** */ Request::Request( const Mobile *_mobile, const Timestamp &_time_sent, const unordered_map &_measurements ): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(_mobile), time_sent(_time_sent), measurements(_measurements), real_position(nullptr) { received_now() ; } Request::Request(const unordered_map &_measurements): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(nullptr), measurements(_measurements), real_position(nullptr) { received_now() ; } Request::Request( const Timestamp &_time_sent, const unordered_map &_measurements ): type(OWL_REQUEST_UNDEFINED), nb_packets(1), mobile(nullptr), time_sent(_time_sent), measurements(_measurements), real_position(nullptr) { 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(nullptr) { 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() ; delete real_position ; } /* *** Read accessors *** */ /** * @param mac_receiver The MAC address of the receiver CP. * @returns A pointer on the found measurement, or nullptr if no * measurement was made by this CP. */ const Measurement* Request::get_measurement(const string &mac_receiver) const { auto m = measurements.find(mac_receiver) ; if (m != measurements.end()) return &m->second ; return nullptr ; } /* *** Write accessors *** */ inline void Request::clear_real_position() { if (real_position) { delete real_position ; real_position = nullptr ; } } 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 set to nullptr, 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 = nullptr ; 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 ; if (real_position == source.real_position) real_position_equal = true ; // equal pointers else if (real_position && source.real_position) real_position_equal = *real_position == *source.real_position ; else real_position_equal = false ; // one of the two is null 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 ; // CSV format version // (this should match OWL_LATEST_AGGREGATION_CSV_FORMAT) constexpr unsigned int aggregation_csv_format = 1 ; csv_line << aggregation_csv_format << ';' ; if (mobile) 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) 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 (auto 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 ? r.mobile->get_mac_addr() : "Unknown_Mobile") << ":" ; // List of Measurements if (r.measurements.empty()) os << " No values" ; else for (auto i = r.measurements.begin() ; i != r.measurements.end() ; ++i) os << '\n' << i->first << ": " << i->second ; return os ; }