#ifndef WIFIGRIDNODE_H #define WIFIGRIDNODE_H #include #include "AccessPoint.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 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) { if (!ap.isValid()) {break;} // reached the end if (getMapAPs()[ap.getAPIdx()].getMAC() == mac) {return ap.getRSSI();} } 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& getMapAPs() { static std::vector list; return list; } protected: /** 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); } /** 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); } };// __attribute__((packed)); #endif // WIFIGRIDNODE_H