181 lines
4.5 KiB
C++
181 lines
4.5 KiB
C++
/*
|
||
* © Copyright 2014 – Urheberrechtshinweis
|
||
* Alle Rechte vorbehalten / All Rights Reserved
|
||
*
|
||
* Programmcode ist urheberrechtlich geschuetzt.
|
||
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
|
||
* Keine Verwendung ohne explizite Genehmigung.
|
||
* (vgl. § 106 ff UrhG / § 97 UrhG)
|
||
*/
|
||
|
||
#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
|