Skip to content

Commit df34002

Browse files
committed
fix: AP slow results and states
- fixes 5 places that were slowing down results and state logic for webUI. The HW was always fast, i just wrote some bad code. - decreases time we wait for new data, which may impact battery- TODO in batt saver mode, or use the headless fw
1 parent db5a2e2 commit df34002

File tree

3 files changed

+125
-77
lines changed

3 files changed

+125
-77
lines changed

Antihunter/full/src/hardware.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ String getDiagnostics() {
790790

791791
std::lock_guard<std::mutex> lock(diagMutex);
792792

793-
if (millis() - lastDiagTime < 1000 && cachedDiag.length() > 0) {
793+
if (millis() - lastDiagTime < 500 && cachedDiag.length() > 0) {
794794
return cachedDiag;
795795
}
796796
lastDiagTime = millis();

Antihunter/full/src/network.cpp

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <AsyncWebSocket.h>
99
#include <RTClib.h>
1010
#include <esp_timer.h>
11+
#include <deque>
1112

1213
extern "C"
1314
{
@@ -62,7 +63,7 @@ extern void randomizeMacAddress();
6263

6364
// WebSocket for terminal
6465
AsyncWebSocket ws("/terminal");
65-
static std::vector<String> terminalBuffer;
66+
static std::deque<String> terminalBuffer;
6667
static const size_t TERMINAL_BUFFER_SIZE = 500;
6768
static bool terminalClientsConnected = false;
6869

@@ -113,7 +114,7 @@ void broadcastToTerminal(const String &message) {
113114

114115
terminalBuffer.push_back(timestamped);
115116
if (terminalBuffer.size() > TERMINAL_BUFFER_SIZE) {
116-
terminalBuffer.erase(terminalBuffer.begin());
117+
terminalBuffer.pop_front();
117118
}
118119
}
119120

@@ -960,7 +961,7 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
960961
let lastScanningState = false;
961962
let lastResultsText = '';
962963
let meshEnabled = true;
963-
let lastTriangulationStartTime = 0; // Track when triangulation scan was started
964+
let lastScanStartTime = 0;
964965
965966
function switchTab(tabName) {
966967
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
@@ -1710,9 +1711,7 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
17101711
}
17111712
}
17121713
} else {
1713-
// Don't reset UI if we just started triangulation (give backend time to update status)
1714-
const timeSinceTriangulationStart = Date.now() - lastTriangulationStartTime;
1715-
const isWithinGracePeriod = timeSinceTriangulationStart < 5000; // 5 second grace period
1714+
const isWithinGracePeriod = (Date.now() - lastScanStartTime) < 3000;
17161715
17171716
if (!isWithinGracePeriod) {
17181717
document.getElementById('scanStatus').innerText = 'Idle';
@@ -3028,9 +3027,10 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
30283027
if (document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA' || document.activeElement.tagName === 'SELECT' || document.activeElement.isContentEditable || window.getSelection().toString().length > 0)) return;
30293028
tickRunning = true;
30303029
try {
3031-
const [diagResponse, droneResponse] = await Promise.all([
3030+
const [diagResponse, droneResponse, resultsResponse] = await Promise.all([
30323031
fetch('/diag'),
3033-
fetch('/drone/status').catch(() => null)
3032+
fetch('/drone/status').catch(() => null),
3033+
fetch('/results').catch(() => null)
30343034
]);
30353035
const diagText = await diagResponse.text();
30363036
const isScanning = diagText.includes('Scanning: yes');
@@ -3095,67 +3095,65 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
30953095
}
30963096
const resultsElement = document.getElementById('r');
30973097
if (resultsElement && !resultsElement.contains(document.activeElement)) {
3098-
if (isScanning) {
3099-
const rr = await fetch('/results');
3100-
const resultsText = await rr.text();
3098+
if ((isScanning || (lastScanningState && !isScanning)) && resultsResponse) {
3099+
const resultsText = await resultsResponse.text();
31013100
if (resultsText !== lastResultsText) {
31023101
lastResultsText = resultsText;
3103-
requestAnimationFrame(() => {
3104-
const expandedCards = new Set();
3105-
const expandedDetails = new Map();
3106-
const contents = resultsElement.querySelectorAll('[id$="Content"]');
3107-
for (const content of contents) {
3108-
if (content.style.display !== 'none') {
3109-
expandedCards.add(content.id);
3110-
}
3111-
}
3112-
const openDetails = resultsElement.querySelectorAll('details[open]');
3113-
for (const details of openDetails) {
3114-
const summary = details.querySelector('summary');
3115-
if (summary && summary.textContent) {
3116-
expandedDetails.set(summary.textContent.trim(), true);
3102+
if (isScanning) {
3103+
requestAnimationFrame(() => {
3104+
const expandedCards = new Set();
3105+
const expandedDetails = new Map();
3106+
const contents = resultsElement.querySelectorAll('[id$="Content"]');
3107+
for (const content of contents) {
3108+
if (content.style.display !== 'none') {
3109+
expandedCards.add(content.id);
3110+
}
31173111
}
3118-
}
3119-
resultsElement.innerHTML = parseAndStyleResults(resultsText);
3120-
for (const contentId of expandedCards) {
3121-
const content = document.getElementById(contentId);
3122-
if (content) {
3123-
const iconId = contentId.replace('Content', 'Icon');
3124-
const icon = document.getElementById(iconId);
3125-
content.style.display = 'block';
3126-
if (icon) {
3127-
icon.style.transform = 'rotate(0deg)';
3128-
icon.textContent = '▼';
3112+
const openDetails = resultsElement.querySelectorAll('details[open]');
3113+
for (const details of openDetails) {
3114+
const summary = details.querySelector('summary');
3115+
if (summary && summary.textContent) {
3116+
expandedDetails.set(summary.textContent.trim(), true);
31293117
}
31303118
}
3131-
}
3132-
const allDetails = resultsElement.querySelectorAll('details');
3133-
for (const details of allDetails) {
3134-
const summary = details.querySelector('summary');
3135-
if (summary) {
3136-
const summaryText = summary.textContent.trim();
3137-
if (expandedDetails.has(summaryText)) {
3138-
details.open = true;
3139-
const spans = summary.querySelectorAll('span');
3140-
const arrow = spans[spans.length - 1];
3141-
if (arrow) arrow.style.transform = 'rotate(90deg)';
3119+
resultsElement.innerHTML = parseAndStyleResults(resultsText);
3120+
for (const contentId of expandedCards) {
3121+
const content = document.getElementById(contentId);
3122+
if (content) {
3123+
const iconId = contentId.replace('Content', 'Icon');
3124+
const icon = document.getElementById(iconId);
3125+
content.style.display = 'block';
3126+
if (icon) {
3127+
icon.style.transform = 'rotate(0deg)';
3128+
icon.textContent = '▼';
3129+
}
31423130
}
31433131
}
3144-
details.addEventListener('toggle', () => {
3145-
const spans = details.querySelectorAll('summary span');
3146-
const arrow = spans[spans.length - 1];
3147-
if (arrow) {
3148-
arrow.style.transform = details.open ? 'rotate(90deg)' : 'rotate(0deg)';
3132+
const allDetails = resultsElement.querySelectorAll('details');
3133+
for (const details of allDetails) {
3134+
const summary = details.querySelector('summary');
3135+
if (summary) {
3136+
const summaryText = summary.textContent.trim();
3137+
if (expandedDetails.has(summaryText)) {
3138+
details.open = true;
3139+
const spans = summary.querySelectorAll('span');
3140+
const arrow = spans[spans.length - 1];
3141+
if (arrow) arrow.style.transform = 'rotate(90deg)';
3142+
}
31493143
}
3150-
});
3151-
}
3152-
});
3144+
details.addEventListener('toggle', () => {
3145+
const spans = details.querySelectorAll('summary span');
3146+
const arrow = spans[spans.length - 1];
3147+
if (arrow) {
3148+
arrow.style.transform = details.open ? 'rotate(90deg)' : 'rotate(0deg)';
3149+
}
3150+
});
3151+
}
3152+
});
3153+
} else {
3154+
resultsElement.innerHTML = parseAndStyleResults(resultsText);
3155+
}
31533156
}
3154-
} else if (lastScanningState && !isScanning) {
3155-
const rr = await fetch('/results');
3156-
const resultsText = await rr.text();
3157-
lastResultsText = resultsText;
3158-
resultsElement.innerHTML = parseAndStyleResults(resultsText);
31593157
}
31603158
}
31613159
lastScanningState = isScanning;
@@ -3262,10 +3260,7 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
32623260
// Check if triangulation mode is selected
32633261
const isTriangulation = fd.has('triangulate') && fd.get('triangulate') === '1';
32643262
3265-
// Track when triangulation was started
3266-
if (isTriangulation) {
3267-
lastTriangulationStartTime = now;
3268-
}
3263+
lastScanStartTime = now;
32693264
32703265
// Immediately update UI to show scanning state for ALL scan types
32713266
const scanStatusEl = document.getElementById('scanStatus');
@@ -3294,7 +3289,13 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
32943289
};
32953290
}
32963291
3297-
console.log('[SCAN] Form submitted at', new Date().toISOString());
3292+
const resultsElScan = document.getElementById('r');
3293+
if (resultsElScan && !resultsElScan.contains(document.activeElement)) {
3294+
lastResultsText = '';
3295+
const modeVal = parseInt(document.querySelector('#s select[name="mode"]')?.value ?? '2');
3296+
const modeLabel = ['WiFi', 'BLE', 'WiFi+BLE'][modeVal] ?? 'WiFi+BLE';
3297+
resultsElScan.innerHTML = parseAndStyleResults('Target scan starting...\nMode: ' + modeLabel + '\n');
3298+
}
32983299
32993300
fetch('/scan', {
33003301
method: 'POST',
@@ -3405,6 +3406,7 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
34053406
34063407
state.inProgress = true;
34073408
state.lastSubmit = now;
3409+
lastScanStartTime = now;
34083410
34093411
const scanStatusEl = document.getElementById('scanStatus');
34103412
if (scanStatusEl) {
@@ -3446,6 +3448,12 @@ static const char INDEX_HTML[] PROGMEM = R"HTML(
34463448
}, 500);
34473449
};
34483450
3451+
const resultsElSniffer = document.getElementById('r');
3452+
if (resultsElSniffer && !resultsElSniffer.contains(document.activeElement)) {
3453+
lastResultsText = '';
3454+
resultsElSniffer.innerHTML = parseAndStyleResults('Scan starting...\n');
3455+
}
3456+
34493457
if (detectionMethod === 'baseline') {
34503458
const rssiThreshold = document.getElementById('baselineRssiThreshold').value;
34513459
const duration = document.getElementById('baselineDuration').value;
@@ -3720,6 +3728,7 @@ void startWebServer()
37203728
req->send(200, "text/plain", forever ? ("Scan starting (forever) - " + modeStr) : ("Scan starting for " + String(secs) + "s - " + modeStr));
37213729

37223730
if (!workerTaskHandle) {
3731+
scanning = true;
37233732
xTaskCreatePinnedToCore(listScanTask, "scan", 8192, (void*)(intptr_t)(forever ? 0 : secs), 1, &workerTaskHandle, 1);
37243733
}
37253734
});
@@ -4222,9 +4231,10 @@ server->on("/baseline/config", HTTP_GET, [](AsyncWebServerRequest *req)
42224231
req->send(200, "text/plain", forever ? "Deauth detection starting (forever)" : ("Deauth detection starting for " + String(secs) + "s"));
42234232

42244233
if (!blueTeamTaskHandle) {
4234+
scanning = true;
42254235
xTaskCreatePinnedToCore(blueTeamTask, "blueteam", 12288, (void*)(intptr_t)(forever ? 0 : secs), 1, &blueTeamTaskHandle, 1);
42264236
}
4227-
4237+
42284238
} else if (detection == "baseline") {
42294239
currentScanMode = SCAN_BOTH;
42304240
if (secs < 0) secs = 0;
@@ -4236,8 +4246,9 @@ server->on("/baseline/config", HTTP_GET, [](AsyncWebServerRequest *req)
42364246
("Baseline detection starting for " + String(secs) + "s"));
42374247

42384248
if (!workerTaskHandle) {
4239-
xTaskCreatePinnedToCore(baselineDetectionTask, "baseline", 12288,
4240-
(void*)(intptr_t)(forever ? 0 : secs),
4249+
scanning = true;
4250+
xTaskCreatePinnedToCore(baselineDetectionTask, "baseline", 12288,
4251+
(void*)(intptr_t)(forever ? 0 : secs),
42414252
1, &workerTaskHandle, 1);
42424253
}
42434254

@@ -4264,6 +4275,7 @@ server->on("/baseline/config", HTTP_GET, [](AsyncWebServerRequest *req)
42644275
("Randomization detection starting for " + String(secs) + "s - " + modeStr));
42654276

42664277
if (!workerTaskHandle) {
4278+
scanning = true;
42674279
xTaskCreatePinnedToCore(randomizationDetectionTask, "randdetect", 8192,
42684280
(void*)(intptr_t)(forever ? 0 : secs),
42694281
1, &workerTaskHandle, 1);
@@ -4292,8 +4304,9 @@ server->on("/baseline/config", HTTP_GET, [](AsyncWebServerRequest *req)
42924304
("Device scan starting for " + String(secs) + "s - " + modeStr));
42934305

42944306
if (!workerTaskHandle) {
4295-
xTaskCreatePinnedToCore(snifferScanTask, "sniffer", 12288,
4296-
(void*)(intptr_t)(forever ? 0 : secs),
4307+
scanning = true;
4308+
xTaskCreatePinnedToCore(snifferScanTask, "sniffer", 12288,
4309+
(void*)(intptr_t)(forever ? 0 : secs),
42974310
1, &workerTaskHandle, 1);
42984311
}
42994312

@@ -4308,6 +4321,7 @@ server->on("/baseline/config", HTTP_GET, [](AsyncWebServerRequest *req)
43084321
("Drone detection starting for " + String(secs) + "s"));
43094322

43104323
if (!workerTaskHandle) {
4324+
scanning = true;
43114325
xTaskCreatePinnedToCore(droneDetectorTask, "drone", 12288,
43124326
(void*)(intptr_t)(forever ? 0 : secs),
43134327
1, &workerTaskHandle, 1);

Antihunter/full/src/scanner.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,15 +2217,14 @@ void listScanTask(void *pv) {
22172217
int secs = (int)(intptr_t)pv;
22182218
bool forever = (secs <= 0);
22192219

2220-
// Clear old results
2220+
String modeStr = (currentScanMode == SCAN_WIFI) ? "WiFi" :
2221+
(currentScanMode == SCAN_BLE) ? "BLE" : "WiFi+BLE";
2222+
22212223
{
22222224
std::lock_guard<std::mutex> lock(antihunter::lastResultsMutex);
2223-
antihunter::lastResults.clear();
2225+
antihunter::lastResults = "Target scan starting...\nMode: " + std::string(modeStr.c_str()) + "\n";
22242226
}
22252227

2226-
String modeStr = (currentScanMode == SCAN_WIFI) ? "WiFi" :
2227-
(currentScanMode == SCAN_BLE) ? "BLE" : "WiFi+BLE";
2228-
22292228
Serial.printf("[SCAN] List scan %s (%s)...\n",
22302229
forever ? "(forever)" : String(String("for ") + secs + " seconds").c_str(),
22312230
modeStr.c_str());
@@ -2324,7 +2323,7 @@ void listScanTask(void *pv) {
23242323
Hit h;
23252324

23262325
uint32_t nextTriResultsUpdate = millis() + 2000;
2327-
2326+
uint32_t lastListProgressUpdate = millis() + 1000;
23282327

23292328
while ((forever && !stopRequested) ||
23302329
(!forever && (int)(millis() - lastScanStart) < secs * 1000 && !stopRequested)) {
@@ -2730,6 +2729,41 @@ void listScanTask(void *pv) {
27302729
}
27312730
}
27322731

2732+
if (!triangulationActive && (int32_t)(millis() - lastListProgressUpdate) >= 0) {
2733+
std::string pr = "Target scan (IN PROGRESS)\nElapsed: ";
2734+
pr += std::to_string((millis() - lastScanStart) / 1000) + "s";
2735+
if (!forever && secs > 0) {
2736+
int32_t rem = secs - (int32_t)((millis() - lastScanStart) / 1000);
2737+
if (rem > 0) pr += " / " + std::to_string(secs) + "s (" + std::to_string(rem) + "s left)";
2738+
}
2739+
pr += "\nTarget hits: " + std::to_string(totalHits.load());
2740+
pr += "\nWiFi frames: " + std::to_string(framesSeen.load());
2741+
pr += "\nBLE frames: " + std::to_string(bleFramesSeen.load()) + "\n\n";
2742+
2743+
std::vector<Hit> snap = hitsLog;
2744+
std::sort(snap.begin(), snap.end(), [](const Hit& a, const Hit& b) { return a.rssi > b.rssi; });
2745+
int shown = 0;
2746+
for (const auto& sh : snap) {
2747+
if (shown++ >= 50) break;
2748+
char mb[18];
2749+
snprintf(mb, sizeof(mb), "%02X:%02X:%02X:%02X:%02X:%02X",
2750+
sh.mac[0], sh.mac[1], sh.mac[2], sh.mac[3], sh.mac[4], sh.mac[5]);
2751+
pr += std::string(sh.isBLE ? "BLE " : "WiFi") + " " + mb;
2752+
pr += " RSSI=" + std::to_string(sh.rssi) + "dBm";
2753+
if (!sh.isBLE && sh.ch > 0) pr += " CH=" + std::to_string(sh.ch);
2754+
if (strlen(sh.name) > 0 && strcmp(sh.name, "Unknown") != 0 && strcmp(sh.name, "WiFi") != 0)
2755+
pr += " " + std::string(sh.name);
2756+
pr += "\n";
2757+
}
2758+
if (snap.size() > 50) pr += "... (" + std::to_string(snap.size() - 50) + " more)\n";
2759+
2760+
{
2761+
std::lock_guard<std::mutex> lock(antihunter::lastResultsMutex);
2762+
antihunter::lastResults = pr;
2763+
}
2764+
lastListProgressUpdate = millis() + 2000;
2765+
}
2766+
27332767
vTaskDelay(pdMS_TO_TICKS(150));
27342768
}
27352769
if (triangulationActive) {

0 commit comments

Comments
 (0)