Public Access
- lib/wifi (host-tested): channel occupancy (neighbour spill, signal weighting, quietest of 1/6/11) and a signal tracker (history, lost detection, click interval) - WifiService: scan results carry BSSID, channel and security; a scan can target one channel for quick tracker refreshes; endListScans() turns the radio back off when Wi-Fi is disabled - Wi-Fi Tools App: networks nearby, channel occupancy bars, signal tracker with clicks (m to mute) - M1 plan: Monitoring-mode views and captures deferred Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
53 lines
1.6 KiB
C++
53 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <deque>
|
|
|
|
namespace roro {
|
|
|
|
// Follows one access point's signal over repeated scans, for finding where it is.
|
|
class SignalTracker {
|
|
public:
|
|
static constexpr int kNoSignal = -127;
|
|
static constexpr uint32_t kLostAfterMs = 5000;
|
|
static constexpr uint32_t kFastestClickMs = 60;
|
|
static constexpr uint32_t kSlowestClickMs = 1200;
|
|
|
|
explicit SignalTracker(size_t historySize) : size_(historySize) {}
|
|
|
|
void seen(int rssi, uint32_t nowMs) {
|
|
push(rssi);
|
|
latest_ = rssi;
|
|
lastSeenMs_ = nowMs;
|
|
everSeen_ = true;
|
|
}
|
|
void missed() { push(kNoSignal); } // a scan that didn't see it
|
|
|
|
bool lost(uint32_t nowMs) const { return !everSeen_ || nowMs - lastSeenMs_ >= kLostAfterMs; }
|
|
int latest() const { return latest_; }
|
|
const std::deque<int>& history() const { return history_; }
|
|
|
|
// Time between clicks: fast when the signal is strong (close), slow when faint.
|
|
static uint32_t clickIntervalMs(int rssi) {
|
|
if (rssi >= -35) return kFastestClickMs;
|
|
if (rssi <= -95) return kSlowestClickMs;
|
|
float t = (rssi + 95) / 60.0f; // 0 at -95 dBm, 1 at -35 dBm
|
|
return static_cast<uint32_t>(kSlowestClickMs - t * (kSlowestClickMs - kFastestClickMs));
|
|
}
|
|
|
|
private:
|
|
void push(int v) {
|
|
history_.push_back(v);
|
|
if (history_.size() > size_) history_.pop_front();
|
|
}
|
|
|
|
size_t size_;
|
|
std::deque<int> history_;
|
|
int latest_ = kNoSignal;
|
|
uint32_t lastSeenMs_ = 0;
|
|
bool everSeen_ = false;
|
|
};
|
|
|
|
} // namespace roro
|