mirror of
https://github.com/meshtastic/firmware.git
synced 2026-11-07 06:44:33 -05:00
fix(mesh): coerce coordinate traffic to the position channel on event builds (#11545)
Under USERPREFS_BLOCK_POSITION_ON_EVENT_CHANNEL every coordinate packet a client aimed at the event channel was rejected with the "Location sharing is disabled on this channel" notification - including the phone's own location feed. Both apps hand a GPS-less node its fix as a POSITION_APP packet addressed to the node itself on channel 0; that packet never leaves the device (Router::sendLocal delivers it locally) but resolved to the event channel and was dropped before PositionModule saw it. Result: the toast on every location tick, and nodes without a GPS never learned a position to share on their private channel. Position traffic now converges on the position channel - findPositionChannel(), the first channel with non-zero on-wire precision, which is never the event channel: - From-us-to-us coordinate packets are exempt from the event block. - Local coordinate sends aimed at the event channel (phone share-location, request-position, waypoints, any module/UI originator) are moved onto the position channel in Router::sendLocal and PhoneAPI instead of rejected. The client notification is only sent when no channel carries positions at all. - A position request DM'd to us on the event channel is answered on the position channel at that channel's precision (request_id preserved, same reply throttle); the requester's coordinates are still not stored, forwarded, relayed or published. want_response from the bitfield is merged before the event-channel decode short-circuit so such requests are seen. - PositionModule::sendOurPosition, positionUnchangedSinceLastSend and MeshService::trySendPosition use the shared helper instead of three copies of the same walk. Non-event builds are unaffected: the coercion compiles out and the helper matches the previous walk. Tests: coverage-event-policy (test_event_channel_phone_api, test_event_channel_router, test_position_precision, test_mqtt, test_nexthop_routing) and the same suites with the policy off. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8fe246e250
commit
a5fc95f774
11 files changed
+411
-40
No files matched your search
@@ -289,6 +289,27 @@ meshtastic_MeshPacket *PositionModule::allocReply()
|
||||
return reply;
|
||||
}
|
||||
|
||||
void PositionModule::replyOnPositionChannel(const meshtastic_MeshPacket &req)
|
||||
{
|
||||
uint8_t positionChannel;
|
||||
if (!findPositionChannel(positionChannel)) {
|
||||
LOG_DEBUG("Skip position reply to 0x%08x: position sharing disabled on all channels", getFrom(&req));
|
||||
return;
|
||||
}
|
||||
if (!service)
|
||||
return;
|
||||
|
||||
precision = getPositionPrecisionForChannel(positionChannel);
|
||||
meshtastic_MeshPacket *reply = allocReply(); // reply throttle + precision-0/no-fix guards live here
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
setReplyTo(reply, req);
|
||||
reply->channel = positionChannel; // not the channel the request came in on
|
||||
LOG_INFO("Reply to position request from 0x%08x on position channel %u", getFrom(&req), positionChannel);
|
||||
service->sendToMesh(reply);
|
||||
}
|
||||
|
||||
meshtastic_MeshPacket *PositionModule::allocAtakPli()
|
||||
{
|
||||
LOG_INFO("Send TAK V2 PLI packet");
|
||||
@@ -374,12 +395,11 @@ void PositionModule::sendOurPosition()
|
||||
currentGeneration = radioGeneration;
|
||||
|
||||
// If we changed channels, ask everyone else for their latest info
|
||||
for (uint8_t channelNum = 0; channelNum < 8; channelNum++) {
|
||||
if (getPositionPrecisionForChannel(channelNum) != 0) {
|
||||
LOG_INFO("Send pos@%x:6 to mesh (wantReplies=%d)", localPosition.timestamp, requestReplies);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies, channelNum);
|
||||
return;
|
||||
}
|
||||
uint8_t positionChannel;
|
||||
if (findPositionChannel(positionChannel)) {
|
||||
LOG_INFO("Send pos@%x:6 to mesh (wantReplies=%d)", localPosition.timestamp, requestReplies);
|
||||
sendOurPosition(NODENUM_BROADCAST, requestReplies, positionChannel);
|
||||
return;
|
||||
}
|
||||
LOG_INFO("Skip pos@%x:6 broadcast; position sharing disabled on all channels", localPosition.timestamp);
|
||||
}
|
||||
@@ -467,12 +487,10 @@ bool PositionModule::positionUnchangedSinceLastSend(const meshtastic_PositionLit
|
||||
// precision). Default nodes gauge movement at that on-wire (public-clamped) resolution;
|
||||
// trackers use their own configured (unclamped) precision so finer moves still count.
|
||||
uint32_t precisionBits = 0;
|
||||
for (uint8_t ch = 0; ch < 8; ch++) {
|
||||
if (getPositionPrecisionForChannel(ch) == 0)
|
||||
continue;
|
||||
uint8_t ch;
|
||||
if (findPositionChannel(ch)) {
|
||||
precisionBits =
|
||||
useConfiguredPrecision ? getPositionPrecisionForChannel(channels.getByIndex(ch)) : getPositionPrecisionForChannel(ch);
|
||||
break;
|
||||
}
|
||||
|
||||
return positionWithinPrecisionCell(selfPos.latitude_i, selfPos.longitude_i, lastGpsLatitude, lastGpsLongitude, precisionBits);
|
||||
|
||||
Reference in new issue
Block a user