Pr multi gcs june2026 ap#46
Open
Davidsastresas wants to merge 6 commits into
Open
Conversation
The operator control handler used _operator_control_sysid (param4, the range minimum) as both the sysid range bound and the gcs_main reported in CONTROL_STATUS. When a range is requested, param4 is the minimum id, not necessarily the requesting GCS. Add _operator_control_primary to track the actual requesting GCS (msg.sysid) separately from the range. get_operator_control_sysid() and sysid_is_primary_operator() now use _operator_control_primary, aligning CONTROL_STATUS.gcs_main with the protocol spec: System ID of GCS in control.
A secondary GCS within the operator control range was auto-granted control without going through the takeover path. sysid_is_gcs() matched any GCS in the range, so the same GCS re-requesting branch granted control even when takeover was not allowed. Compare against the primary GCS (msg.sysid) instead of the range, so secondary GCS must go through the takeover notification flow as the protocol requires.
The takeover notification pending flag was set in queue_operator_control_notification() but never read or cleared, and clear_operator_control_notification() was dead code. A request for MSG_OPERATOR_CONTROL_NOTIFICATION outside the queued send path would transmit a stale notification. Replace the flag with a per-channel pending mask, following the statustext pattern: queueing marks all active channels, each channel clears its bit after a successful send, and an ownership change invalidates any notification still queued (which would otherwise go out with gcs_main no longer matching, or broadcast to sysid 0 after a release).
The release path accepted the command from any GCS in the operator control range, so a secondary GCS could strip control from the primary without going through the takeover flow. This is the release-side counterpart of the earlier takeover bypass fix: a secondary that cannot request control without permission must not be able to force a release either. Keep the sysid_is_gcs() check for the uncontrolled case so a release when no operator is set (a no-op) is still only accepted from a recognized GCS.
param3 of MAV_CMD_REQUEST_OPERATOR_CONTROL is specified as 3 to 60 seconds but was forwarded unchecked into the takeover notification, so an out-of-range requester timeout (including 0 from senders that do not set it) was displayed as-is by the owning GCS countdown.
…meout clamp A secondary GCS within the operator control range must now be DENIED when trying to release control; only the primary may release. Also verify that an out-of-range request timeout (param3=120) is clamped to 60 seconds in the notification forwarded to the owning GCS.
This was referenced Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
More information in ArduPilot#33332 (comment).