Bug: MeshCore companion source GPS lat/lon saved incorrectly (6 decimal places off)
Reported by: mattch (v4.9.2, self-hosted Docker)
Summary
When setting GPS coordinates in Configuration > Location for a MeshCore companion source, the values are saved to the device incorrectly — the device receives the integer part of the decimal degree value only (e.g. 40 instead of 40.712776). The MeshMonitor UI appears correct after save because it reads from its own cache, masking the bug.
Root Cause
In src/server/meshcoreNativeBackend.ts, the set_coords command handler called c.setAdvertLatLong(lat, lon) with raw decimal degrees:
case 'set_coords':
await c.setAdvertLatLong(Number(params.lat), Number(params.lon));
The underlying meshcore.js method sendCommandSetAdvertLatLon writes coordinates via DataView.setInt32() (i.e. raw int32LE). MeshCore's wire protocol expects fixed-point microdegrees (degrees × 1,000,000). Passing 40.712776 as a float to writeInt32LE results in the value being truncated to 40 on the device — off by exactly 6 decimal places.
The cache update below the call was already computing the correct fixed-point value (Math.round(lat * 1e6)), but the value sent to the device was wrong.
Fix
Pre-convert to fixed-point microdegrees before calling setAdvertLatLong, and reuse the computed values for the cache update:
case 'set_coords': {
const latFixed = Math.round(Number(params.lat) * 1e6);
const lonFixed = Math.round(Number(params.lon) * 1e6);
await c.setAdvertLatLong(latFixed, lonFixed);
if (this.cachedSelfInfo) {
this.cachedSelfInfo.advLat = latFixed;
this.cachedSelfInfo.advLon = lonFixed;
}
return { ok: true };
}
Affected versions
- v4.9.2 confirmed; likely all versions with MeshCore native backend support.
Workaround
Set GPS position directly via the MeshCore iOS/Android companion app or CLI until a patched build is available.
Authored by NodeZero 0️⃣
Bug: MeshCore companion source GPS lat/lon saved incorrectly (6 decimal places off)
Reported by: mattch (v4.9.2, self-hosted Docker)
Summary
When setting GPS coordinates in Configuration > Location for a MeshCore companion source, the values are saved to the device incorrectly — the device receives the integer part of the decimal degree value only (e.g.
40instead of40.712776). The MeshMonitor UI appears correct after save because it reads from its own cache, masking the bug.Root Cause
In
src/server/meshcoreNativeBackend.ts, theset_coordscommand handler calledc.setAdvertLatLong(lat, lon)with raw decimal degrees:The underlying
meshcore.jsmethodsendCommandSetAdvertLatLonwrites coordinates viaDataView.setInt32()(i.e. rawint32LE). MeshCore's wire protocol expects fixed-point microdegrees (degrees × 1,000,000). Passing40.712776as a float towriteInt32LEresults in the value being truncated to40on the device — off by exactly 6 decimal places.The cache update below the call was already computing the correct fixed-point value (
Math.round(lat * 1e6)), but the value sent to the device was wrong.Fix
Pre-convert to fixed-point microdegrees before calling
setAdvertLatLong, and reuse the computed values for the cache update:Affected versions
Workaround
Set GPS position directly via the MeshCore iOS/Android companion app or CLI until a patched build is available.
Authored by NodeZero 0️⃣