needed interface changes [new options] logger for android wifi-ap-optimization new test-cases
171 lines
4.2 KiB
C++
171 lines
4.2 KiB
C++
#ifndef WIFIGRIDNODE_H
|
|
#define WIFIGRIDNODE_H
|
|
|
|
#include <cstdint>
|
|
#include "AccessPoint.h"
|
|
#include "../../misc/Debug.h"
|
|
|
|
/**
|
|
* rssi model-estimation for one AP, denoted by its index [among all APs present within the map]
|
|
* the signal strength is stored as uint8_t and allows a granularity of 0.25 dB between -40 and -103 dB
|
|
*/
|
|
struct WiFiGridNodeAP {
|
|
|
|
private:
|
|
|
|
static const uint8_t UNUSED_IDX = 255;
|
|
|
|
private:
|
|
|
|
/** access-point index -> max 255 APs/Map */
|
|
uint8_t idx;
|
|
|
|
/** access-point rssi */
|
|
uint8_t rssi;
|
|
|
|
public:
|
|
|
|
/** empty ctor */
|
|
WiFiGridNodeAP() : idx(UNUSED_IDX), rssi(0) {
|
|
int i = 0; (void) i;
|
|
}
|
|
|
|
/** ctor */
|
|
WiFiGridNodeAP(const int idx, const float rssi) : idx(idx), rssi(stretch(rssi)) {
|
|
int i = 0; (void) i;
|
|
}
|
|
|
|
|
|
/** is this entry valid/used? */
|
|
bool isValid() const {return idx != UNUSED_IDX;}
|
|
|
|
/** set AP and its signal strength */
|
|
void set(const int apIdx, const float rssi) {
|
|
this->idx = apIdx;
|
|
this->rssi = stretch(rssi);
|
|
}
|
|
|
|
/** get the predicted signal-strength */
|
|
float getRSSI() const {return unstretch(rssi);}
|
|
|
|
/** get the access-point's index */
|
|
int getAPIdx() const {return idx;}
|
|
|
|
private:
|
|
|
|
/** [-40:-103] -> [0:252] => this allows 0.25 steps */
|
|
static inline int8_t stretch(float rssi) {
|
|
if (rssi > -40) {rssi = -40;}
|
|
if (rssi < -103) {rssi = -103;}
|
|
return std::round((-rssi - 40) * 4);
|
|
}
|
|
|
|
/** [0:252] -> [-40:-103] */
|
|
static inline float unstretch(const float rssi) {
|
|
return -(rssi / 4.0f + 40.0f);
|
|
}
|
|
|
|
};// __attribute__((packed));
|
|
|
|
|
|
/**
|
|
* base-class for grid-nodes that contain wifi signal-strength estimations.
|
|
* such estimations are calculated offline and added to each node.
|
|
* this also allows for using very complex signal-strength estimation models
|
|
*/
|
|
template <int maxAccessPoints> struct WiFiGridNode {
|
|
|
|
/** contains the 10 strongest APs measureable at this position */
|
|
WiFiGridNodeAP strongestAPs[maxAccessPoints];
|
|
|
|
|
|
/** ctor */
|
|
explicit WiFiGridNode() : strongestAPs() {
|
|
;
|
|
}
|
|
|
|
|
|
/** get the maximum number of APs each node is able to store */
|
|
int getMaxAPs() const {return maxAccessPoints;}
|
|
|
|
/**
|
|
* get the RSSI for the given AP
|
|
* returns 0 if unknown
|
|
*/
|
|
float getRSSI(const std::string& mac) const {
|
|
return getRSSI(MACAddress(mac));
|
|
}
|
|
|
|
/**
|
|
* get the RSSI for the given AP
|
|
* returns 0 if unknown
|
|
*/
|
|
float getRSSI(const MACAddress mac) const {
|
|
for (const WiFiGridNodeAP& ap : strongestAPs) {
|
|
//std::cout << getMapAPs()[ap.getAPIdx()].getMAC().asString() << std::endl;
|
|
//std::cout << mac.asString() << std::endl;
|
|
if (!ap.isValid()) {break;} // reached the end of all APs visible on this node
|
|
if (getMapAPs()[ap.getAPIdx()].getMAC() == mac) {return ap.getRSSI();} // does this APs MAC match with the requested MAC? -> found!
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/** get the number of access-points visible at this node */
|
|
int getNumVisibleAPs() const {
|
|
for (int i = 0; i < getMaxAPs(); ++i) {
|
|
if (!strongestAPs[i].isValid()) {return i;}
|
|
}
|
|
return getMaxAPs();
|
|
}
|
|
|
|
/** shared vector of all accesspoints the are present within the map. the IDX referes to this vector */
|
|
static std::vector<AccessPoint>& getMapAPs() {
|
|
static std::vector<AccessPoint> list;
|
|
return list;
|
|
}
|
|
|
|
|
|
protected:
|
|
|
|
static constexpr const char* name = "WiFiGridNode";
|
|
|
|
/** serialize static members */
|
|
static void staticSerialize(std::ostream& out) {
|
|
|
|
// number of APs within map
|
|
const int numAPs = getMapAPs().size();
|
|
|
|
// serialize number and APs within map
|
|
out.write((const char*) &numAPs, sizeof(numAPs));
|
|
out.write((const char*) getMapAPs().data(), sizeof(getMapAPs()[0])*numAPs);
|
|
|
|
Log::add(name, "serialized " + std::to_string(numAPs) + " APs");
|
|
|
|
}
|
|
|
|
/** deserialize static members */
|
|
static void staticDeserialize(std::istream& inp) {
|
|
|
|
// get number of APs within map
|
|
int numAPs;
|
|
inp.read((char*) &numAPs, sizeof(numAPs));
|
|
|
|
// allocate
|
|
getMapAPs().resize(numAPs);
|
|
|
|
// deserialize APs within map
|
|
inp.read((char*) getMapAPs().data(), sizeof(getMapAPs()[0])*numAPs);
|
|
|
|
Log::add(name, "de-serialized " + std::to_string(numAPs) + " APs");
|
|
std::string aps; for (const AccessPoint& ap : getMapAPs()) {aps += ap.getMAC().asString() + " ";}
|
|
Log::add(name, aps);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};// __attribute__((packed));
|
|
|
|
#endif // WIFIGRIDNODE_H
|