MSP-over-MAVLink tunnel#11718
Conversation
Output of docs/development/msp/gen_docs.sh. Corrects the checked-in MSP docs, which were last generated from a different branch (FC version and several upstream enums did not match this branch's sources).
Fix generate.sh/generate.bat to build the storm32.xml dialect that INAV includes (337-message STorM32/ArduPilot/common set) instead of the catch-all dialect, and regenerate. Provides the MLRS radio link messages used by the multi-port MAVLink runtime.
The regenerated library moves the merged MAV_CMD enum out of common/common.h into storm32/storm32.h. Switch the first MAVLink include (rx/mavlink.h, which wins the include guard for every TU) to the storm32 dialect, drop telemetry/mavlink.c's local APM plane/copter mode enum copies in favor of the generated ArduPilot dialect enums, and silence the new single-channel helper warnings under warnings-as-errors.
Modularize the monolithic telemetry/mavlink.c into src/main/mavlink/ (runtime, ports, streams, routing, modes, command, guided) plus fc/fc_mavlink.c for FC-facing dispatch, leaving telemetry/mavlink.c as a thin adapter. - Up to MAX_MAVLINK_PORTS (4) concurrent MAVLink ports with per-port runtime state and per-port mavlink_portN_* settings - ArduPilot-style route learning ((sysid,compid) -> ingress port), targeted forwarding, broadcast fan-out, fixed local identity MAV_COMP_ID_AUTOPILOT1 - Half-duplex TX backoff on shared serialrx_halfduplex MAVLink RX ports - mLRS radio link stats/information/flow-control handling per port - HIGH_LATENCY2 service with per-port high_latency setting and MAV_CMD_CONTROL_HIGH_LATENCY - Bounded RX work per scheduler invocation (MAVLINK_RX_BYTE_BUDGET) - MAVLink moved behind the MCU_FLASH_SIZE > 512 gate Incoming message surface otherwise matches the previous single-port implementation (COMMAND_INT DO_REPOSITION / DO_CHANGE_ALTITUDE, RC override, RADIO_STATUS, ADSB, param stub, heartbeat), now also accepted via COMMAND_LONG. MAVLink mission protocol is intentionally absent at this point in the stack and returns rewritten as a transfer state machine in a later PR; merge only as part of the stack.
Core slice of the full mavlink_multiport2 test suite: routing identity, RC override forwarding, mLRS link handling, RADIO_STATUS flow control, telemetry payloads, param stub, and the reposition/change-altitude command surface. Later stack PRs re-add their own test sections. 19/19 passing (cmake -DTOOLCHAIN=none, target mavlink_unittest).
Picks up the MAVLink module enums added by the multi-port split: dispatch results, radio types (mLRS, none), and autopilot types.
Live SITL test tooling for the multi-port runtime: mav_multi_benchmark.py runs baseline and stress scenarios across 1-4 active MAVLink ports (MSP failure rates, heartbeat warmup, reconnect handling); mav_multi_sweep.py drives configuration sweeps. Config paths point at the in-tree results directory; runtime artifacts are gitignored.
Restores the branch's protocol-service layer on top of the multi-port core: - PING and TIMESYNC replies - REQUEST_DATA_STREAM handling and per-message SET/GET_MESSAGE_INTERVAL command surface over the existing override storage - MAV_CMD_REQUEST_MESSAGE (incl. MESSAGE_INTERVAL query), REQUEST_PROTOCOL_VERSION, REQUEST_AUTOPILOT_CAPABILITIES, GET_HOME_POSITION - UBlox ellipsoid altitude, speed and heading accuracy retained in the GPS solution and emitted in GPS_RAW_INT when valid - Arming-disable reasons broadcast as STATUSTEXT once a MAVLink port is active; INAV flight-mode change notices incl. GCS NAV enter/exit - Per-port OSD-derived STATUSTEXT de-spam (changed text immediately, notice 30s / warning 10s / critical 5s repeat intervals) Unit slice: 38/38 passing.
Rewritten mission protocol replacing the old ad-hoc counters (absent since the modular split): owned transfers tracking initiating system, component and ingress port; upload retries and timeouts; one-item retransmission; final MISSION_ACK; out-of-sequence recovery; explicit cancellation; legacy MISSION_REQUEST answered with MISSION_ITEM_INT. Uploads are staged and committed only on success, QGC planned-home item 0 is skipped, modifier items (speed/delay/altitude) fold onto the correct INAV waypoint, and persistence failures restore the previous mission. Successful uploads and clears update nonvolatile storage. Adds 1 Hz MISSION_CURRENT, active-item download flags, and MISSION_ITEM_REACHED broadcast from a navigation-side reached latch. Includes the live SITL mission test rig (src/test/mavlink/missions) and routing compliance harness (src/test/mavlink/routing). Unit slice: 58/58 passing. Mission translation to INAV's MSP waypoint model is lossy; downloads are best-effort reconstruction, not canonical mission backups.
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Standalone 8-check pass/fail rig against a self-started SITL with the known-good multiport serial layout: MSP on UART1, MAVLink receiver telemetry and RC override on UART2, GCS heartbeat, mission upload and readback, stream-rate and message-rate control on UART3. Previously lived only in the development workspace and was never committed.
- MAV_CMD_COMPONENT_ARM_DISARM and MSP2_INAV_ARM_DISARM through the normal arming path, succeeding only when the requested state is reached - RTH via a temporary BOXNAVRTH source on the RC mode selector (activateRTHMode) instead of the failsafe/geozone forced-RTH latch; wired to MAV_CMD_NAV_RETURN_TO_LAUNCH, ArduPilot DO_SET_MODE RTL, MSP2_INAV_ACTIVATE_RTH, and Programming Framework operation 61. Cleared by a pilot flight-mode change or disarm - QGC/ArduPilot pause: DO_SET_MODE Loiter/PosHold/Brake enters normal PosHold at the current position via a temporary BOXNAVPOSHOLD source - Normal current-position LAND (transient waypoint, uploaded mission untouched) via MAV_CMD_NAV_LAND, MSP2_INAV_ACTIVATE_LANDING, PF op 62 - MAV_CMD_DO_SET_HOME through the native waypoint-0 backend - MSP2_INAV_TIMESYNC returning the MAVLink TIMESYNC boot clock - Temporary fixed-wing loiter-radius override: DO_REPOSITION.param3 (meters) or int32 loiterRadius appended to MSP2_INAV_SET_GLOBAL_TARGET (cm); volatile, cleared on disarm/reboot, only active in PosHold - SET_POSITION_TARGET_GLOBAL_INT / _LOCAL_NED guided handling - MAV_CMD_CONDITION_YAW; explicit unsupported MAV_CMD_NAV_TAKEOFF stub - GCSN OSD flight-mode element while GCS navigation is active Unit slice: 81/81 passing.
MSP transport over MAVLink TUNNEL (private payload type 0x8001, MAVLink 2 only) so the Configurator can talk MSP over an existing MAVLink telemetry link. Reuses the MSP parser/encoder through narrow msp_serial seams; replies are fragmented and returned on the ingress port only; MSPv1/v2 framing symmetry is preserved end-to-end. Reboot post-processing is allowed; serial passthrough and ESC 4-way are rejected before dispatch. Malformed payload lengths are dropped and stale partial frames time out. Reply/frame buffers are file-scope, not task stack. Companion configurator branch adds the MAVLink Tunnel wireless option. Full mavlink_unittest suite: 86/86 passing. Final PR of the mavlink_multiport2 stack: tree now matches the feature branch (remaining deltas are upstream maintenance-10.x drift only).
docs/Mavlink.md documents the full MAVLink stack: multiport + routing,
datastream groups and CLI settings, identity/capabilities, mLRS
integration, supported outgoing/incoming messages and commands, mode
mappings, mission behavior and MSP parity gaps, MSP-over-MAVLink
tunnel, and high-latency mode. Updated from the development branch to
cover flight-mode-change STATUSTEXT notices and reworded for mainline.
docs/Settings.md regenerated from settings.yaml (picks up the per-port
mavlink_port{1-4}_* settings).
End-to-end live harness against a running SITL/FC MAVLink endpoint: API version, FC variant/version, build info, EEPROM write, reboot over the tunnel, and reconnect recovery after reboot.
|
This #11472 PR has been split into a sequence of PR's by inav-claude for easier review and handling, but i'll include a whole laydown of what it entails as final product here.
Upstream PRs can't base on fork branches, so all 7 target What this isA ground-up rework of INAV's MAVLink implementation: from a single-port, single-file telemetry bolt-on into a modular MAVLink subsystem with:
Routing design follows ArduPilot's Developed on ArchitectureThe monolithic
Headers: built against the checked-in STorM32 dialect (337-message STorM32/ArduPilot/common superset) because it carries OlliW's mLRS-specific messages. The regen moved the merged Feature laydownMulti-port
Routing
Streams & protocol services
Telemetry detail
Missions
Command parity (MAVLink + MSPv2 + Programming Framework)
mLRS integration
High latency
MSP-over-MAVLink tunnel
SITL/simulator fixes
Design decisions worth remembering
Verification
Known limits / non-goals
|
Part 7/7 of the mavlink_multiport2 stack — final part; the tree now carries the complete feature set.
MSP-over-MAVLink tunnel
MSP transport over the MAVLink Tunnel service (private payload type
0x8001, MAVLink 2 only), so the INAV Configurator can talk MSP over an existing MAVLink telemetry link — typically a radio that exposes no separate MSP transport. The companion configurator PR adds a "MAVLink Tunnel" option under Wireless mode with SYSID selection for multi-vehicle networks.msp_serialseams (byte parser, encode-to-buffer, command processing) — no duplicate MSP framing logic.TUNNELmessages and returned on the ingress port only;target_component = 0is accepted for local delivery but never fanned out to other ports.MSP_REBOOTpost-processing is supported over the tunnel; serial passthrough and ESC 4-way passthrough are rejected before dispatch.Documentation
This PR also lands the complete user-facing
docs/Mavlink.md(multiport/routing, datastream groups and CLI settings, mLRS integration, supported messages/commands, mode mappings, mission behavior and MSP parity gaps, tunnel, high-latency mode) and regeneratesdocs/Settings.mdfor the per-portmavlink_port{1-4}_*settings.Testing
mavlink_unittestsuite: 86/86 passing (tunnel cases: malformed-length rejection, pre-dispatch passthrough rejection, reboot ingress-port handling, stale-frame reset, multi-message reply fragmentation).src/test/mavlink/tunnel/) covering that same sequence against a running SITL/FC.Companion PRs:
inav-configurator:mavlink_multiport2(tunnel UI + wrapping),mspapi2:mavlink_multiport2.