mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-07-27 00:48:23 +08:00
feat(mavlink): support FTP ListDirectoryWithTime (#27542)
Add support for the MAVLink FTP ListDirectoryWithTime command (opcode 16), which returns directory listings with each file's last-modification time appended as decimal seconds since the UNIX epoch (0 if unknown). This lets a GCS retrieve file timestamps without downloading the files, which is useful for log download. The plain ListDirectory output is unchanged, and clients fall back to it when the server NAKs with UnknownCommand. Signed-off-by: Julian Oes <julian@oes.ch>
This commit is contained in:
@@ -171,6 +171,10 @@ MavlinkFTP::_process_request(
|
||||
errorCode = _workList(payload);
|
||||
break;
|
||||
|
||||
case kCmdListDirectoryWithTime:
|
||||
errorCode = _workList(payload, true);
|
||||
break;
|
||||
|
||||
case kCmdOpenFileRO:
|
||||
errorCode = _workOpen(payload, O_RDONLY);
|
||||
break;
|
||||
@@ -322,7 +326,7 @@ void MavlinkFTP::_constructPath(char *dst, int dst_len, const char *path) const
|
||||
|
||||
/// @brief Responds to a List command
|
||||
MavlinkFTP::ErrorCode
|
||||
MavlinkFTP::_workList(PayloadHeader *payload)
|
||||
MavlinkFTP::_workList(PayloadHeader *payload, bool include_time)
|
||||
{
|
||||
_constructPath(_work_buffer1, _work_buffer1_len, _data_as_cstring(payload));
|
||||
|
||||
@@ -380,6 +384,7 @@ MavlinkFTP::_workList(PayloadHeader *payload)
|
||||
}
|
||||
|
||||
uint32_t fileSize = 0;
|
||||
uint32_t fileTime = 0; // seconds since the UNIX epoch, 0 if unknown
|
||||
char direntType;
|
||||
|
||||
// Determine the directory entry type
|
||||
@@ -401,6 +406,7 @@ MavlinkFTP::_workList(PayloadHeader *payload)
|
||||
|
||||
if (stat(_work_buffer2, &st) == 0) {
|
||||
fileSize = st.st_size;
|
||||
fileTime = st.st_mtime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,8 +439,16 @@ MavlinkFTP::_workList(PayloadHeader *payload)
|
||||
_work_buffer2[0] = '\0';
|
||||
|
||||
} else if (direntType == kDirentFile) {
|
||||
// Files send filename and file length
|
||||
int ret = snprintf(_work_buffer2, _work_buffer2_len, "%s\t%" PRIu32, result->d_name, fileSize);
|
||||
// Files send filename and file length, optionally followed by the modification time
|
||||
int ret;
|
||||
|
||||
if (include_time) {
|
||||
ret = snprintf(_work_buffer2, _work_buffer2_len, "%s\t%" PRIu32 "\t%" PRIu32, result->d_name, fileSize, fileTime);
|
||||
|
||||
} else {
|
||||
ret = snprintf(_work_buffer2, _work_buffer2_len, "%s\t%" PRIu32, result->d_name, fileSize);
|
||||
}
|
||||
|
||||
bool buf_is_ok = ((ret > 0) && (ret < _work_buffer2_len));
|
||||
|
||||
if (!buf_is_ok) {
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
kCmdRename, ///< Rename <path1> to <path2>
|
||||
kCmdCalcFileCRC32, ///< Calculate CRC32 for file at <path>
|
||||
kCmdBurstReadFile, ///< Burst download session file
|
||||
kCmdListDirectoryWithTime, ///< List files in <path> from <offset>, including last-modification time
|
||||
|
||||
kRspAck = 128, ///< Ack response
|
||||
kRspNak ///< Nak response
|
||||
@@ -125,7 +126,7 @@ private:
|
||||
void _reply(mavlink_file_transfer_protocol_t *ftp_req);
|
||||
int _copy_file(const char *src_path, const char *dst_path, size_t length);
|
||||
|
||||
ErrorCode _workList(PayloadHeader *payload);
|
||||
ErrorCode _workList(PayloadHeader *payload, bool include_time = false);
|
||||
ErrorCode _workOpen(PayloadHeader *payload, int oflag);
|
||||
ErrorCode _workRead(PayloadHeader *payload);
|
||||
ErrorCode _workBurst(PayloadHeader *payload, uint8_t target_system_id, uint8_t target_component_id);
|
||||
|
||||
Reference in New Issue
Block a user