Files
PX4-Autopilot/Tools
Jacob Dahl dcfce4343a feat(mavlink): serve and accept packed parameters as @PARAM/param.pck (#28435)
* feat(mavlink): serve packed parameters as @PARAM/param.pck

QGC already downloads ArduPilot parameters as a packed FTP file, which
is much more reliable on lossy SiK links than the PARAM_VALUE firehose.
Serve the same format from PX4 so a hash miss can use that path.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(mavlink): serialize the full message when resending a cached FTP reply

_last_reply caches only the header, PayloadHeader and four data bytes,
but the resend path handed that 19-byte array to the serializer as a
complete mavlink_file_transfer_protocol_t, which reads 254 bytes and
transmits whatever follows the cache. The decoded request is dead once
the resend decision is made, so expand the cache into it instead of
adding another message to the receiver thread's stack. Clear the unused
payload before caching so a resent NAK matches the original.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* test(mavsdk_tests): download parameters via MAVLink FTP

Fetch @PARAM/param.pck through MAVSDK's burst download on SIH and check
every entry against the PARAM_VALUE stream, so the packed format and the
FTP server's session, size and EOF handling stay covered by the SITL
tests that QGC and MAVSDK both rely on.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(mavlink): cache FTP Open ACKs whose size LSB is 5

_reply skipped the compact cache whenever data[0] was kErrNoSessionsAvailable. On a NAK that is the error code; on an Open ACK it is the file size LSB. A lost Open ACK for param.pck of that length was retried as a second Open and failed.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* feat(tools): download packed parameters over MAVFTP

Host-side check of @PARAM/param.pck against the PARAM_VALUE stream.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(mavlink): pad so a defaulted value does not straddle an FTP block

pack() kept the last 4 bytes of an entry in one chunk. With withdefaults those bytes are the default, so the value can still split. QGC always requests defaults; a hole-fill then retries one chunk with a live param_get().

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(mavlink): snapshot param.pck at open so a param_set cannot corrupt it

Pack the used set once into a heap buffer. Reads memcpy that snapshot, so a value change during the download cannot shift later entries or splice two generations across a retried FTP block.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(mavlink): freeze param.pck membership instead of snapshotting the file

Keep which parameters appear and whether each includes a default in bitsets (~1 KB). Pack values live. Layout cannot shift mid-download; a retried block cannot splice a number.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* style(mavlink): format MavlinkFtpParamTest.cpp

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* refactor(mavlink): keep FTP work buffers as members

@PARAM/param.pck is a connect-time path, not the rare path the lazy new[] was for. send() could free the buffers after 2 s of no request while a burst was still running. Fold them into the instance (495 B) and always idle-close the session at 30 s.

A new Open takes over the single session so a lost Terminate on a slow link does not NAK until that close.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* fix(tools): make mavftp_param.py reliable on a radio link

pymavlink applied FTP timings after ResetSessions, wrote param.pck?withdefaults=1 into cwd, and bumped the session id on Open retry (PX4 only ACKs session 0). Set radio timings at construction, pin session 0, retry a missed Open, and treat a complete decode as success.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

* feat(mavlink): accept packed parameter FTP uploads

CreateFile/Write/Terminate of @PARAM/param.pck applies the ArduPilot
packed stream so a GCS can bulk-load without a PARAM_SET round trip per
value. Unknown and read-only names are skipped; Terminate NAKs a
truncated file or the with-defaults magic.

* test(mavsdk_tests): upload MPC_XY_P via packed param FTP

Pin the SIH upload case to a known float instead of whatever
get_all_params() returns first.

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-09-08 20:16:14 -06:00
..