diff --git a/lib/BleFingerprint/BleFingerprint.cpp b/lib/BleFingerprint/BleFingerprint.cpp index 8d2c10f..fe4d1b1 100644 --- a/lib/BleFingerprint/BleFingerprint.cpp +++ b/lib/BleFingerprint/BleFingerprint.cpp @@ -16,22 +16,19 @@ class ClientCallbacks : public BLEClientCallbacks { static ClientCallbacks clientCB; -BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff) : filteredDistance{FilteredDistance(fcmin, beta, dcutoff)} { +BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice) { firstSeenMillis = millis(); address = NimBLEAddress(advertisedDevice->getAddress()); addressType = advertisedDevice->getAddressType(); - rssi = advertisedDevice->getRSSI(); - raw = dist = pow(10, float(get1mRssi() - rssi) / (10.0f * BleFingerprintCollection::absorption)); + for (auto& channel : channels) + channel.observe(firstSeenMillis, get1mRssi(), advertisedDevice->getRSSI()); seenCount = 1; queryReport = nullptr; fingerprintAddress(); } void BleFingerprint::setInitial(const BleFingerprint &other) { - rssi = other.rssi; - dist = other.dist; - raw = other.raw; - filteredDistance = other.filteredDistance; + channels = other.channels; } bool BleFingerprint::shouldHide(const String &s) { @@ -66,10 +63,10 @@ bool BleFingerprint::setId(const String &newId, short newIdType, const String &n allowQuery = newQuery; if (allowQuery) { qryAttempts = 0; - if (rssi < -80) { + if (getMaxObservedRssi() < -80) { qryDelayMillis = 30000; lastQryMillis = millis(); - } else if (rssi < -70) { + } else if (getMaxObservedRssi() < -70) { qryDelayMillis = 5000; lastQryMillis = millis(); } @@ -408,8 +405,16 @@ void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertis } } -bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice) { - lastSeenMillis = millis(); +void BleChannelObservation::observe(unsigned long timestamp, int rssi1m, int rssi) { + this->rssi = rssi; + raw = pow(10, float(rssi1m - rssi) / (10.0f * BleFingerprintCollection::absorption)); + filter.addMeasurement(raw); + dist = filter.getDistance(); + vari = filter.getVariance(); + lastSeenMillis = timestamp; +} + +bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice, uint8_t channel) { reported = false; seenCount++; @@ -418,11 +423,8 @@ bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice) { if (ignore || hidden) return false; - rssi = advertisedDevice->getRSSI(); - raw = pow(10, float(get1mRssi() - rssi) / (10.0f * BleFingerprintCollection::absorption)); - filteredDistance.addMeasurement(raw); - dist = filteredDistance.getDistance(); - vari = filteredDistance.getVariance(); + lastChannel = channel; + channels[ble_channel_to_index(channel)].observe(millis(), get1mRssi(), advertisedDevice->getRSSI()); if (!added) { added = true; @@ -439,11 +441,46 @@ bool BleFingerprint::fill(JsonObject *doc) { if (idType) (*doc)[F("idType")] = idType; (*doc)[F("rssi@1m")] = get1mRssi(); - (*doc)[F("rssi")] = rssi; + (*doc)[F("rssi")] = getMaxObservedRssi(); + switch (lastChannel) { + case 37: + (*doc)[F("rssi37")] = channels[0].rssi; + (*doc)[F("raw37")] = serialized(String(channels[0].raw, 2)); + (*doc)[F("distance37")] = serialized(String(channels[0].dist, 2)); + (*doc)[F("var37")] = serialized(String(channels[0].vari, 2)); + break; + case 38: + (*doc)[F("rssi38")] = channels[1].rssi; + (*doc)[F("raw38")] = serialized(String(channels[1].raw, 2)); + (*doc)[F("distance38")] = serialized(String(channels[1].dist, 2)); + (*doc)[F("var38")] = serialized(String(channels[1].vari, 2)); + break; + case 39: + (*doc)[F("rssi39")] = channels[2].rssi; + (*doc)[F("raw39")] = serialized(String(channels[2].raw, 2)); + (*doc)[F("distance39")] = serialized(String(channels[2].dist, 2)); + (*doc)[F("var39")] = serialized(String(channels[2].vari, 2)); + break; + } + (*doc)[F("channel")] = lastChannel; - if (isnormal(raw)) (*doc)[F("raw")] = serialized(String(raw, 2)); - if (isnormal(dist)) (*doc)[F("distance")] = serialized(String(dist, 2)); - if (isnormal(vari)) (*doc)[F("var")] = serialized(String(vari, 2)); + float weightedDistances = 0; + float sumWeights = 0; + float sumVariances = 0; + // FIXME: weight channels by timestamp of last packet, so we can ignore stale values + for (const auto& channel : channels) { + float weight = 1 / std::max(channel.vari, 0.05f); + weightedDistances += channel.dist * weight; + sumWeights += weight; + sumVariances += channel.vari; + } + float fusedDistance = weightedDistances / sumWeights; + float fusedVariance = sumVariances / 3; + (*doc)[F("distance")] = serialized(String(fusedDistance, 2)); + (*doc)[F("var")] = serialized(String(fusedVariance, 2)); + + auto minRaw = std::min_element(channels.begin(), channels.end(), [](const BleChannelObservation& a, const BleChannelObservation& b) { return a.raw < b.raw; })->raw; + (*doc)[F("raw")] = serialized(String(minRaw, 2)); if (close) (*doc)[F("close")] = true; (*doc)[F("int")] = (millis() - firstSeenMillis) / seenCount; @@ -459,17 +496,19 @@ bool BleFingerprint::report(JsonObject *doc) { if (ignore || idType <= ID_TYPE_RAND_MAC || hidden) return false; if (reported) return false; + auto minObservedDistance = getMinObservedDistance(); + auto maxDistance = BleFingerprintCollection::maxDistance; - if (maxDistance > 0 && dist > maxDistance) + if (maxDistance > 0 && minObservedDistance > maxDistance) return false; auto now = millis(); - if ((abs(dist - lastReported) < BleFingerprintCollection::skipDistance) && (lastReportedMillis > 0) && (now - lastReportedMillis < BleFingerprintCollection::skipMs)) + if ((abs(minObservedDistance - lastReported) < BleFingerprintCollection::skipDistance) && (lastReportedMillis > 0) && (now - lastReportedMillis < BleFingerprintCollection::skipMs)) return false; if (fill(doc)) { lastReportedMillis = now; - lastReported = dist; + lastReported = minObservedDistance; reported = true; return true; } @@ -479,10 +518,10 @@ bool BleFingerprint::report(JsonObject *doc) { bool BleFingerprint::query() { if (!allowQuery || isQuerying) return false; - if (rssi < -90) return false; // Too far away + if (getMaxObservedRssi() < -90) return false; // Too far away auto now = millis(); - if (now - lastSeenMillis > 5) return false; // Haven't seen lately + if (now - getLastSeenMillis() > 5000) return false; // Haven't seen lately if (now - lastQryMillis < qryDelayMillis) return false; // Too soon isQuerying = true; @@ -490,7 +529,7 @@ bool BleFingerprint::query() { bool success = false; - Serial.printf("%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, now - lastSeenMillis); + Serial.printf("%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), getMaxObservedRssi(), now - getLastSeenMillis()); NimBLEClient *pClient = NimBLEDevice::getClientListSize() ? NimBLEDevice::getClientByPeerAddress(address) : nullptr; if (!pClient) pClient = NimBLEDevice::getDisconnectedClient(); @@ -516,29 +555,31 @@ bool BleFingerprint::query() { } else { qryAttempts++; qryDelayMillis = min(int(pow(10, qryAttempts)), 60000); - Serial.printf("%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis); + Serial.printf("%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), getMaxObservedRssi(), qryAttempts, qryDelayMillis); } isQuerying = false; return true; } bool BleFingerprint::shouldCount() { - if (!close && rssi > CLOSE_RSSI + BleFingerprintCollection::rxAdjRssi) { + if (!close && getMaxObservedRssi() > CLOSE_RSSI + BleFingerprintCollection::rxAdjRssi) { BleFingerprintCollection::Close(this, true); close = true; - } else if (close && rssi < LEFT_RSSI + BleFingerprintCollection::rxAdjRssi) { + } else if (close && getMaxObservedRssi() < LEFT_RSSI + BleFingerprintCollection::rxAdjRssi) { BleFingerprintCollection::Close(this, false); close = false; } + auto minObservedDistance = getMinObservedDistance(); + bool prevCounting = counting; if (ignore || !countable) counting = false; else if (getMsSinceLastSeen() > BleFingerprintCollection::countMs) counting = false; - else if (counting && dist > BleFingerprintCollection::countExit) + else if (counting && minObservedDistance > BleFingerprintCollection::countExit) counting = false; - else if (!counting && dist <= BleFingerprintCollection::countEnter) + else if (!counting && minObservedDistance <= BleFingerprintCollection::countEnter) counting = true; if (prevCounting != counting) { @@ -549,5 +590,6 @@ bool BleFingerprint::shouldCount() { } void BleFingerprint::expire() { - lastSeenMillis = 0; + for (auto& channel : channels) + channel.lastSeenMillis = 0; } diff --git a/lib/BleFingerprint/BleFingerprint.h b/lib/BleFingerprint/BleFingerprint.h index a491c8d..daf9e33 100644 --- a/lib/BleFingerprint/BleFingerprint.h +++ b/lib/BleFingerprint/BleFingerprint.h @@ -60,11 +60,42 @@ #define ID_TYPE_KNOWN_MAC short(210) #define ID_TYPE_ALIAS short(250) +static inline uint8_t ble_channel_to_index(int8_t channel) { + auto index = channel - 37; + if (index < 0 || index > 2) + return 0; + return index; +} + +enum class BleChannel { + Channel37 = 0, + Channel38 = 1, + Channel39 = 2, + Any +}; + +#define ONE_EURO_FCMIN 1e-1f +#define ONE_EURO_BETA 1e-3f +#define ONE_EURO_DCUTOFF 5e-3f + +struct BleChannelObservation { + int rssi { NO_RSSI }; + float raw { 0 }; + float dist { 0 }; + float vari { 0 }; + unsigned long lastSeenMillis { 0 }; + + void observe(unsigned long timestamp, int rssi1m, int rssi); + + private: + FilteredDistance filter { ONE_EURO_FCMIN, ONE_EURO_BETA, ONE_EURO_DCUTOFF }; +}; + class BleFingerprint { public: - BleFingerprint(NimBLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff); + BleFingerprint(NimBLEAdvertisedDevice *advertisedDevice); - bool seen(BLEAdvertisedDevice *advertisedDevice); + bool seen(BLEAdvertisedDevice *advertisedDevice, uint8_t channel); bool fill(JsonObject *doc); @@ -86,17 +117,24 @@ class BleFingerprint { const short getIdType() const { return idType; } - const float getDistance() const { return dist; } + const float getMinObservedDistance() const { + return std::min_element(channels.begin(), channels.end(), [](const BleChannelObservation& a, const BleChannelObservation& b) { return a.dist < b.dist; })->dist; + } - const int getRssi() const { return rssi; } - const int getRawRssi() const { return rssi; } + const int getMaxObservedRssi() const { + return std::max_element(channels.begin(), channels.end(), [](const BleChannelObservation& a, const BleChannelObservation& b) { return a.rssi < b.rssi; })->rssi; + } const int get1mRssi() const; void set1mRssi(int8_t rssi) { calRssi = rssi; } const NimBLEAddress getAddress() const { return address; } - const unsigned long getMsSinceLastSeen() const { return lastSeenMillis ? millis() - lastSeenMillis : 4294967295; }; + unsigned long getLastSeenMillis() const { + return std::max_element(channels.begin(), channels.end(), [](const BleChannelObservation& a, const BleChannelObservation& b) { return a.lastSeenMillis < b.lastSeenMillis; })->lastSeenMillis; + } + + const unsigned long getMsSinceLastSeen() const { return millis() - getLastSeenMillis(); }; const unsigned long getMsSinceFirstSeen() const { return millis() - firstSeenMillis; }; @@ -129,15 +167,15 @@ class BleFingerprint { NimBLEAddress address; String id, name; short int idType = NO_ID_TYPE; - int rssi = NO_RSSI; + uint8_t lastChannel; + std::array channels; int8_t calRssi = NO_RSSI, bcnRssi = NO_RSSI, mdRssi = NO_RSSI, asRssi = NO_RSSI; unsigned int qryAttempts = 0, qryDelayMillis = 0; - float raw = 0, dist = 0, vari = 0, lastReported = 0, temp = 0, humidity = 0; - unsigned long firstSeenMillis, lastSeenMillis = 0, lastReportedMillis = 0, lastQryMillis = 0; + float lastReported = 0, temp = 0, humidity = 0; + unsigned long firstSeenMillis, lastReportedMillis = 0, lastQryMillis = 0; unsigned long seenCount = 1, lastSeenCount = 0; uint16_t mv = 0; uint8_t battery = 0xFF, addressType = 0xFF; - FilteredDistance filteredDistance; std::unique_ptr queryReport = nullptr; static bool shouldHide(const String &s); diff --git a/lib/BleFingerprint/BleFingerprintCollection.cpp b/lib/BleFingerprint/BleFingerprintCollection.cpp index ec3511a..9c9f742 100644 --- a/lib/BleFingerprint/BleFingerprintCollection.cpp +++ b/lib/BleFingerprint/BleFingerprintCollection.cpp @@ -49,12 +49,12 @@ void Close(BleFingerprint *f, bool close) { } } -void Seen(BLEAdvertisedDevice *advertisedDevice) { +void Seen(BLEAdvertisedDevice *advertisedDevice, uint8_t channel) { BLEAdvertisedDevice copy = *advertisedDevice; if (onSeen) onSeen(true); BleFingerprint *f = GetFingerprint(©); - if (f->seen(©) && onAdd) + if (f->seen(©, channel) && onAdd) onAdd(f); if (onSeen) onSeen(false); } @@ -205,7 +205,7 @@ BleFingerprint *getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice) { if (it != fingerprints.rend()) return *it; - auto created = new BleFingerprint(advertisedDevice, ONE_EURO_FCMIN, ONE_EURO_BETA, ONE_EURO_DCUTOFF); + auto created = new BleFingerprint(advertisedDevice); auto it2 = std::find_if(fingerprints.begin(), fingerprints.end(), [created](BleFingerprint *f) { return f->getId() == created->getId(); }); if (it2 != fingerprints.end()) { auto found = *it2; diff --git a/lib/BleFingerprint/BleFingerprintCollection.h b/lib/BleFingerprint/BleFingerprintCollection.h index 61a510d..0ff219a 100644 --- a/lib/BleFingerprint/BleFingerprintCollection.h +++ b/lib/BleFingerprint/BleFingerprintCollection.h @@ -3,10 +3,6 @@ #include "BleFingerprint.h" -#define ONE_EURO_FCMIN 1e-1f -#define ONE_EURO_BETA 1e-3f -#define ONE_EURO_DCUTOFF 5e-3f - #ifndef ALLOW_BLE_CONTROLLER_RESTART_AFTER_SECS #define ALLOW_BLE_CONTROLLER_RESTART_AFTER_SECS 1800 #endif @@ -30,7 +26,7 @@ bool Config(String &id, String &json); void Close(BleFingerprint *f, bool close); void Count(BleFingerprint *f, bool counting); -void Seen(BLEAdvertisedDevice *advertisedDevice); +void Seen(BLEAdvertisedDevice *advertisedDevice, uint8_t channel); BleFingerprint *GetFingerprint(BLEAdvertisedDevice *advertisedDevice); void CleanupOldFingerprints(); const std::vector GetCopy(); diff --git a/lib/handlers/MiFloraHandler.cpp b/lib/handlers/MiFloraHandler.cpp index d230f43..2a0d554 100644 --- a/lib/handlers/MiFloraHandler.cpp +++ b/lib/handlers/MiFloraHandler.cpp @@ -91,7 +91,7 @@ bool forceFloraServiceDataMode(BLERemoteService* floraService) { // Setting the void fillDeviceData(DynamicJsonDocument* doc, BleFingerprint* f) { (*doc)[F("id")] = f->getId(); (*doc)[F("mac")] = f->getMac(); - (*doc)[F("rssi")] = f->getRssi(); + (*doc)[F("rssi")] = f->getMaxObservedRssi(); } bool getFloraData(DynamicJsonDocument* doc, BLERemoteService* floraService, BleFingerprint* f) { diff --git a/lib/handlers/NameModelHandler.cpp b/lib/handlers/NameModelHandler.cpp index 7971325..f1bdc24 100644 --- a/lib/handlers/NameModelHandler.cpp +++ b/lib/handlers/NameModelHandler.cpp @@ -7,14 +7,14 @@ bool requestData(NimBLEClient* pClient, BleFingerprint* f) { std::string sName = pClient->getValue(genericAccessService, nameChar); if (!sName.empty() && sMdl.find(sName) == std::string::npos && sName != "Apple Watch") { if (f->setId(String("name:") + kebabify(sName).c_str(), ID_TYPE_QUERY_NAME, String(sName.c_str()))) { - Serial.printf("\u001b[38;5;104m%u Name | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sName.c_str()); + Serial.printf("\u001b[38;5;104m%u Name | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi(), sName.c_str()); } return true; } if (!sMdl.empty()) { if (f->setId(String("apple:") + kebabify(sMdl).c_str(), ID_TYPE_QUERY_MODEL, String(sMdl.c_str()))) { - Serial.printf("\u001b[38;5;136m%u Model | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sMdl.c_str()); + Serial.printf("\u001b[38;5;136m%u Model | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi(), sMdl.c_str()); } return true; } diff --git a/platformio.ini b/platformio.ini index c86fc44..7700395 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,6 +27,8 @@ build_flags = -Wno-switch-unreachable -Wno-stringop-overflow -Wformat-truncation + -Wl,--wrap,r_lld_scan_process_pkt_rx_adv_rep + -Wl,--wrap,r_ke_msg_send -D CONFIG_BT_NIMBLE_TASK_STACK_SIZE=5632 -D CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 -D SCAN_TASK_STACK_SIZE=2562 diff --git a/src/ChannelInfo.cpp b/src/ChannelInfo.cpp new file mode 100644 index 0000000..3b42aca --- /dev/null +++ b/src/ChannelInfo.cpp @@ -0,0 +1,75 @@ +#include "ChannelInfo.h" +#include +#include +#include "esp_attr.h" + +#define BLE_RXDESC_OFFSET 0x1000 + +extern "C" void *r_emi_get_mem_addr_by_offset(size_t offset); +extern "C" void __real_r_lld_scan_process_pkt_rx_adv_rep(int scan_index, unsigned long param_2,int rxdesc_index, void *param_4); +extern "C" void __real_r_ke_msg_send(void *msg); + +struct BleRxDescriptor { + uint16_t a[3]; + uint8_t rssi; + uint8_t channel; + uint16_t b[6]; +}; + +#define BLE_CHANNEL_QUEUE_SIZE 64 + +static DRAM_ATTR std::atomic bleChannelQueue[BLE_CHANNEL_QUEUE_SIZE]; +static DRAM_ATTR uint32_t bleChannelQueueWriteIndex; +static DRAM_ATTR std::atomic bleChannelInfoTriggeredAtLeastOnce; +static DRAM_ATTR bool bleShouldSaveChannel; +static DRAM_ATTR std::atomic bleDiscardedChannelInfo; +static uint32_t bleChannelQueueReadIndex; + +extern "C" void IRAM_ATTR __wrap_r_ke_msg_send(void *msg) { + bleShouldSaveChannel = true; + __real_r_ke_msg_send(msg); +} + +extern "C" void IRAM_ATTR __wrap_r_lld_scan_process_pkt_rx_adv_rep(int scan_index, unsigned long param_2,int rxdesc_index, void *param_4) { + bleChannelInfoTriggeredAtLeastOnce = true; + auto rxdesc = (const BleRxDescriptor*)r_emi_get_mem_addr_by_offset(BLE_RXDESC_OFFSET) + rxdesc_index; + uint16_t channelAndRssi = rxdesc->channel << 8 | rxdesc->rssi; + bleShouldSaveChannel = false; + __real_r_lld_scan_process_pkt_rx_adv_rep(scan_index, param_2, rxdesc_index, param_4); + if (!bleShouldSaveChannel) { + bleDiscardedChannelInfo++; + return; + } + bleChannelQueue[bleChannelQueueWriteIndex % BLE_CHANNEL_QUEUE_SIZE] = channelAndRssi; + bleChannelQueueWriteIndex++; +} + +namespace ChannelInfo { + +uint8_t popChannelInfo(int8_t expectedRssi) { + unsigned long discarded = bleDiscardedChannelInfo.exchange(0); + if (discarded) + Serial.printf("discarded %d rx pkts?\r\n", discarded); + // Ignore the queue if it hasn't been touched by the hook, e.g. due to + // unsupported hardware/firmware changes that would cause + // r_lld_scan_process_pkt_rx_adv_rep not to get called at all. + if (bleChannelInfoTriggeredAtLeastOnce) { + //Serial.printf("wr: %lu, rd: %lu\r\n", (uint32_t)bleChannelQueueWriteIndex, (uint32_t)bleChannelQueueReadIndex); + const auto initialReadIndex = bleChannelQueueReadIndex; + do { + uint16_t channelInfo = bleChannelQueue[bleChannelQueueReadIndex % BLE_CHANNEL_QUEUE_SIZE]; + bleChannelQueueReadIndex++; + // The Bluetooth stack may have discarded some advertisements after + // we've captured the channel value, skip ahead until we find a + // matching RSSI value. + if ((int8_t)(channelInfo & 0xff) == expectedRssi) + return channelInfo >> 8; + } while (bleChannelQueueReadIndex % BLE_CHANNEL_QUEUE_SIZE != initialReadIndex % BLE_CHANNEL_QUEUE_SIZE); + } + // Either the hook isn't working or we probably received more than + // BLE_CHANNEL_QUEUE_SIZE packets since the last call to popChannelInfo(), + // i.e. the channel info we were looking for is gone. + return 37; +} + +} diff --git a/src/ChannelInfo.h b/src/ChannelInfo.h new file mode 100644 index 0000000..a034df2 --- /dev/null +++ b/src/ChannelInfo.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace ChannelInfo { + +uint8_t popChannelInfo(int8_t expectedRssi); + +} \ No newline at end of file diff --git a/src/GUI.cpp b/src/GUI.cpp index 884c05d..725ad5c 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -53,21 +53,21 @@ void Loop() { void Added(BleFingerprint *f) { if (f->getIgnore()) return; - Serial.printf("%u New %s | %s | %-58s%ddBm\r\n", xPortGetCoreID(), f->getAllowQuery() ? "Q" : " ", f->getMac().c_str(), f->getId().c_str(), f->getRssi()); + Serial.printf("%u New %s | %s | %-58s%ddBm\r\n", xPortGetCoreID(), f->getAllowQuery() ? "Q" : " ", f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi()); } void Removed(BleFingerprint *f) { if (f->getIgnore() || !f->getAdded()) return; - Serial.printf("\u001b[38;5;236m%u Del | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi()); + Serial.printf("\u001b[38;5;236m%u Del | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi()); } void Close(BleFingerprint *f) { - Serial.printf("\u001b[32m%u Close | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRawRssi()); + Serial.printf("\u001b[32m%u Close | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi()); Display::Status("C:%s\r\n", f->getId().c_str()); } void Left(BleFingerprint *f) { - Serial.printf("\u001b[33m%u Left | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRawRssi()); + Serial.printf("\u001b[33m%u Left | %s | %-58s%ddBm\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi()); Display::Status("L:%s\r\n", f->getId().c_str()); } void Motion(bool pir, bool radar) { @@ -106,9 +106,9 @@ void Connected(bool wifi, bool mqtt) { void Counting(BleFingerprint *f, bool add) { if (add) - Serial.printf("\u001b[36m%u C# +1 | %s | %-58s%ddBm (%.2fm) %lums\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), f->getDistance(), f->getMsSinceLastSeen()); + Serial.printf("\u001b[36m%u C# +1 | %s | %-58s%ddBm (%.2fm) %lums\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi(), f->getMinObservedDistance(), f->getMsSinceLastSeen()); else - Serial.printf("\u001b[35m%u C# -1 | %s | %-58s%ddBm (%.2fm) %lums\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), f->getDistance(), f->getMsSinceLastSeen()); + Serial.printf("\u001b[35m%u C# -1 | %s | %-58s%ddBm (%.2fm) %lums\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getMaxObservedRssi(), f->getMinObservedDistance(), f->getMsSinceLastSeen()); } void Wifi(unsigned int percent) { diff --git a/src/main.cpp b/src/main.cpp index e3c9c4c..6d8050d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -484,7 +484,7 @@ void reportLoop() { class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice *advertisedDevice) { bleStack = uxTaskGetStackHighWaterMark(nullptr); - BleFingerprintCollection::Seen(advertisedDevice); + BleFingerprintCollection::Seen(advertisedDevice, ChannelInfo::popChannelInfo(advertisedDevice->getRSSI())); } }; diff --git a/src/main.h b/src/main.h index fa00c10..5cae869 100644 --- a/src/main.h +++ b/src/main.h @@ -13,6 +13,7 @@ #include "BleFingerprint.h" #include "BleFingerprintCollection.h" #include "CAN.h" +#include "ChannelInfo.h" #include "Enrollment.h" #include "GUI.h" #include "HttpReleaseUpdate.h"