Skip to content

Commit 2b7ed0d

Browse files
authored
Merge pull request #183 from MeshMapper/dev
Fixed GPS Error stats
2 parents 68cf494 + 966923c commit 2b7ed0d

3 files changed

Lines changed: 72 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MeshCore GOME WarDriver
22

3-
[![Version](https://img.shields.io/badge/version-1.8.6-blue.svg)](https://github.com/MrAlders0n/MeshCore-GOME-WarDriver/releases/tag/v1.8.6)
3+
[![Version](https://img.shields.io/badge/version-1.8.7-blue.svg)](https://github.com/MrAlders0n/MeshCore-GOME-WarDriver/releases/tag/v1.8.7)
44
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
55
[![Platform](https://img.shields.io/badge/platform-Android%20%7C%20iOS-orange.svg)](#platform-support)
66

content/wardrive.js

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ const state = {
545545
lastFix: null, // { lat, lon, accM, tsMs }
546546
bluefyLockEnabled: false,
547547
gpsState: "idle", // "idle", "acquiring", "acquired", "error"
548+
lastGpsFailureReason: null, // "inaccurate", "stale", "denied", "unavailable", "timeout", "error", or null
548549
gpsAgeUpdateTimer: null, // Timer for updating GPS age display
549550
meshMapperTimer: null, // Timer for delayed MeshMapper API call
550551
cooldownEndTime: null, // Timestamp when cooldown period ends
@@ -1483,6 +1484,10 @@ function startSlotRefreshTimer() {
14831484
updateZoneStatusUI(result);
14841485
debugLog(`[GEO AUTH] [SLOT REFRESH] Zone check failed: ${result.reason || 'unknown'}`);
14851486
}
1487+
} else {
1488+
// GPS failed - update dynamic status to show the reason
1489+
debugLog(`[GEO AUTH] [SLOT REFRESH] GPS failed, reason: ${state.lastGpsFailureReason}`);
1490+
updateConnectButtonState();
14861491
}
14871492
}, 30000); // 30 seconds
14881493
debugLog("[GEO AUTH] Started 30s slot refresh timer");
@@ -1517,7 +1522,8 @@ async function performAppLaunchZoneCheck() {
15171522
if (!coords) {
15181523
debugWarn("[GEO AUTH] [INIT] Failed to get valid GPS coordinates after retries");
15191524
updateZoneStatusUI(null, "gps_unavailable");
1520-
// Connect button remains disabled
1525+
// Connect button remains disabled, but update status to show GPS failure reason
1526+
updateConnectButtonState();
15211527
return;
15221528
}
15231529

@@ -2316,6 +2322,7 @@ async function getValidGpsForZoneCheck(maxRetries = 3, retryDelayMs = 5000) {
23162322
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
23172323
continue;
23182324
}
2325+
state.lastGpsFailureReason = "stale";
23192326
return null;
23202327
}
23212328

@@ -2327,14 +2334,29 @@ async function getValidGpsForZoneCheck(maxRetries = 3, retryDelayMs = 5000) {
23272334
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
23282335
continue;
23292336
}
2337+
state.lastGpsFailureReason = "inaccurate";
23302338
return null;
23312339
}
23322340

23332341
debugLog(`[GPS] [GEO AUTH] Valid GPS acquired: lat=${lat.toFixed(6)}, lon=${lng.toFixed(6)}, accuracy=${accuracy_m.toFixed(1)}m, age=${ageMs}ms`);
2342+
state.lastGpsFailureReason = null; // Clear any previous failure reason on success
23342343
return { lat, lon: lng, accuracy_m, timestamp };
23352344

23362345
} catch (error) {
23372346
debugError(`[GPS] [GEO AUTH] GPS acquisition failed (attempt ${attempt}/${maxRetries}): ${error.message}`);
2347+
2348+
// Check for specific GeolocationPositionError codes
2349+
// 1 = PERMISSION_DENIED, 2 = POSITION_UNAVAILABLE, 3 = TIMEOUT
2350+
if (error.code === 1) {
2351+
debugError(`[GPS] [GEO AUTH] GPS permission denied by user`);
2352+
state.lastGpsFailureReason = "denied";
2353+
return null; // Don't retry - user explicitly denied permission
2354+
} else if (error.code === 2) {
2355+
state.lastGpsFailureReason = "unavailable";
2356+
} else if (error.code === 3) {
2357+
state.lastGpsFailureReason = "timeout";
2358+
}
2359+
23382360
if (attempt < maxRetries) {
23392361
debugLog(`[GPS] [GEO AUTH] Retrying in ${retryDelayMs}ms...`);
23402362
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
@@ -2343,6 +2365,10 @@ async function getValidGpsForZoneCheck(maxRetries = 3, retryDelayMs = 5000) {
23432365
}
23442366

23452367
debugError(`[GPS] [GEO AUTH] GPS acquisition failed after ${maxRetries} attempts`);
2368+
// If no specific reason was set, mark as general error
2369+
if (!state.lastGpsFailureReason) {
2370+
state.lastGpsFailureReason = "error";
2371+
}
23462372
return null;
23472373
}
23482374

@@ -6406,8 +6432,25 @@ function updateConnectButtonState() {
64066432
debugLog("[UI] External antenna not selected - showing message in status bar");
64076433
setDynamicStatus("Select external antenna to connect", STATUS_COLORS.warning);
64086434
} else if (!inValidZone) {
6409-
debugLog("[UI] Not in valid zone - showing waiting for location status");
6410-
setDynamicStatus("Waiting for location...", STATUS_COLORS.info);
6435+
// Show more informative message based on GPS failure reason
6436+
let gpsStatusMsg = "Waiting for location...";
6437+
let gpsStatusColor = STATUS_COLORS.info;
6438+
if (state.lastGpsFailureReason === "inaccurate") {
6439+
gpsStatusMsg = "GPS too inaccurate (max 50m)";
6440+
} else if (state.lastGpsFailureReason === "stale") {
6441+
gpsStatusMsg = "GPS too stale, acquiring...";
6442+
} else if (state.lastGpsFailureReason === "denied") {
6443+
gpsStatusMsg = "GPS permission denied";
6444+
gpsStatusColor = STATUS_COLORS.error;
6445+
} else if (state.lastGpsFailureReason === "unavailable") {
6446+
gpsStatusMsg = "GPS unavailable";
6447+
} else if (state.lastGpsFailureReason === "timeout") {
6448+
gpsStatusMsg = "GPS timeout, retrying...";
6449+
} else if (state.lastGpsFailureReason === "error") {
6450+
gpsStatusMsg = "GPS error";
6451+
}
6452+
debugLog(`[UI] Not in valid zone - showing status: ${gpsStatusMsg}`);
6453+
setDynamicStatus(gpsStatusMsg, gpsStatusColor);
64116454
} else {
64126455
debugLog("[UI] External antenna selected and in valid zone - ready to connect");
64136456
// Only set Idle if not showing a disconnect error

docs/STATUS_MESSAGES.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,35 @@ These messages use a hybrid approach: **first display respects 500ms minimum**,
574574
##### Waiting for location...
575575
- **Message**: `"Waiting for location..."`
576576
- **Color**: Blue (info)
577-
- **When**: External antenna is selected but zone check is still in progress (location display shows "Checking...")
577+
- **When**: External antenna is selected but zone check is still in progress with no specific GPS failure
578578
- **Terminal State**: Yes (persists until zone check completes)
579579
- **Notes**: Displayed in Dynamic Status Bar to inform user that the app is waiting for GPS location and zone validation before allowing connection. Once zone check passes, status changes to "Idle" and Connect button becomes enabled.
580580
- **Source**: `content/wardrive.js:updateConnectButtonState()`
581581

582+
##### GPS too inaccurate (max 50m)
583+
- **Message**: `"GPS too inaccurate (max 50m)"`
584+
- **Color**: Blue (info)
585+
- **When**: External antenna is selected but GPS accuracy exceeds 50m threshold after all retries
586+
- **Terminal State**: Yes (persists until GPS improves or zone check passes)
587+
- **Notes**: More specific message explaining why zone check failed. User should move to area with better GPS reception (outdoors, away from buildings). 30s slot refresh timer will auto-retry zone check.
588+
- **Source**: `content/wardrive.js:updateConnectButtonState()`
589+
590+
##### GPS too stale, acquiring...
591+
- **Message**: `"GPS too stale, acquiring..."`
592+
- **Color**: Blue (info)
593+
- **When**: External antenna is selected but GPS data is older than 60 seconds after all retries
594+
- **Terminal State**: Yes (persists until fresh GPS is acquired or zone check passes)
595+
- **Notes**: More specific message explaining why zone check failed. User should wait for fresh GPS fix. 30s slot refresh timer will auto-retry zone check.
596+
- **Source**: `content/wardrive.js:updateConnectButtonState()`
597+
598+
##### GPS unavailable
599+
- **Message**: `"GPS unavailable"`
600+
- **Color**: Blue (info)
601+
- **When**: External antenna is selected but GPS acquisition failed due to error (permissions, hardware, etc.)
602+
- **Terminal State**: Yes (persists until GPS becomes available or zone check passes)
603+
- **Notes**: Generic GPS error message when acquisition fails completely. User should check GPS permissions and hardware.
604+
- **Source**: `content/wardrive.js:updateConnectButtonState()`
605+
582606
##### Select radio power to connect
583607
- **Message**: `"Select radio power to connect"`
584608
- **Color**: Amber (warning)

0 commit comments

Comments
 (0)