fixed umbrella header for stats added error-feedback to wifi optimizers improved logging for wifi optimizers adjusted calling-API for wifi-optimizers
145 lines
3.2 KiB
C++
145 lines
3.2 KiB
C++
#ifndef WIFIFINGERPRINTS_H
|
|
#define WIFIFINGERPRINTS_H
|
|
|
|
#include <fstream>
|
|
|
|
#include "WiFiFingerprint.h"
|
|
#include <iostream>
|
|
|
|
/**
|
|
* helper class to load and save fingerprints.
|
|
* fingerprints are wifi-measurements given at some known location
|
|
* those can be used to e.g. optimize access-point models etc.
|
|
*/
|
|
class WiFiFingerprints {
|
|
|
|
static constexpr const char* name = "Fingerprints";
|
|
|
|
private:
|
|
|
|
// /** the file to save the calibration model to */
|
|
// std::string file;
|
|
|
|
/** all fingerprints (position -> measurements) within the model */
|
|
std::vector<WiFiFingerprint> fingerprints;
|
|
|
|
public:
|
|
|
|
/** empty ctor */
|
|
WiFiFingerprints() {
|
|
|
|
}
|
|
|
|
/** ctor from file */
|
|
WiFiFingerprints(const std::string& file) {
|
|
load(file);
|
|
}
|
|
|
|
const std::vector<WiFiFingerprint>& getFingerprints() const {
|
|
return fingerprints;
|
|
}
|
|
|
|
std::vector<WiFiFingerprint>& getFingerprints() {
|
|
return fingerprints;
|
|
}
|
|
|
|
/** attach the given fingerprint */
|
|
void add(const WiFiFingerprint& fp) {
|
|
fingerprints.push_back(fp);
|
|
}
|
|
|
|
/** get all fingerprints that measured exactly the given mac [no VAP grouping] */
|
|
const std::vector<WiFiFingerprint> getFingerprintsFor(const MACAddress& mac) const {
|
|
|
|
std::vector<WiFiFingerprint> res;
|
|
|
|
// process each fingerprint location
|
|
for (const WiFiFingerprint& _fp : fingerprints) {
|
|
|
|
// start with an empty copy
|
|
WiFiFingerprint fp = _fp; fp.measurements.entries.clear();
|
|
|
|
// only add the measurements that belong to the requested mac
|
|
for (const WiFiMeasurement& _m : _fp.measurements.entries) {
|
|
if (_m.getAP().getMAC() == mac) {
|
|
fp.measurements.entries.push_back(_m);
|
|
}
|
|
}
|
|
if (fp.measurements.entries.size() > 0) { // got some measurements for this AP?
|
|
res.push_back(fp);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
/** deserialize the model */
|
|
void load(const std::string& file) {
|
|
|
|
// open and check
|
|
std::ifstream inp(file.c_str());
|
|
if (inp.bad() || inp.eof() || ! inp.is_open()) { return; }
|
|
|
|
// read all entries
|
|
while (!inp.eof()) {
|
|
|
|
// each section starts with [fingerprint]
|
|
std::string section;
|
|
inp >> section;
|
|
if (inp.eof()) {break;}
|
|
if (section != "[fingerprint]") {throw Exception("error!");}
|
|
|
|
// deserialize it
|
|
WiFiFingerprint wfp;
|
|
wfp.read(inp);
|
|
if (wfp.measurements.entries.empty()) {continue;}
|
|
fingerprints.push_back(wfp);
|
|
|
|
}
|
|
|
|
Log::add(name, "loaded " + std::to_string(fingerprints.size()) + " fingerprints");
|
|
|
|
inp.close();
|
|
|
|
}
|
|
|
|
|
|
/** serialize the model */
|
|
void save(const std::string& file) {
|
|
|
|
// open and check
|
|
std::ofstream out(file.c_str());
|
|
if (out.bad()) {throw Exception("error while opening " + file + " for write");}
|
|
|
|
// write all entries
|
|
for (const WiFiFingerprint& wfp : fingerprints) {
|
|
out << "[fingerprint]\n";
|
|
wfp.write(out);
|
|
}
|
|
|
|
// done
|
|
out.close();
|
|
|
|
}
|
|
|
|
/** get the fingerprint for the given location. if no fingerprint exists, an empty one is created! */
|
|
WiFiFingerprint& getFingerprint(const Point3 pos_m) {
|
|
|
|
// try to find an existing one
|
|
for (WiFiFingerprint& wfp : fingerprints) {
|
|
// get within range of floating-point rounding issues
|
|
if (wfp.pos_m.getDistance(pos_m) < 0.01) {return wfp;}
|
|
}
|
|
|
|
// create a new one and return its reference
|
|
WiFiFingerprint wfp(pos_m);
|
|
fingerprints.push_back(wfp);
|
|
return fingerprints.back();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif // WIFIFINGERPRINTS_H
|