QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
MockLinkFTP.h
Go to the documentation of this file.
1#pragma once
2
3#include <optional>
4
5#include <QtCore/QByteArray>
6#include <QtCore/QFile>
7#include <QtCore/QHash>
8#include <QtCore/QObject>
9#include <QtCore/QStringList>
10
11#include "MAVLinkFTP.h"
12
13class MockLink;
14
17class MockLinkFTP : public QObject
18{
19 Q_OBJECT
20
21public:
22 MockLinkFTP(uint8_t systemIdServer, uint8_t componentIdServer, MockLink *mockLink);
24
27 void setFileList(const QStringList &fileList) { _fileList = fileList; }
28
30 struct LogFile {
31 QString name;
32 int size = 0;
33 uint32_t mtime = 0;
34 };
35
38 void setLogFiles(const QList<LogFile> &logFiles);
39
41 QList<LogFile> logFiles() const { return _logFiles; }
42
45 QByteArray logFileContents(const QString &name) const;
46
49 void setBurstReadDelayMs(int delayMs) { _burstReadDelayMs = delayMs; }
50
52 void setParamPckEnabled(bool enabled) { _paramPckEnabled = enabled; }
53
55 void setSingleSessionEnforced(bool enforced) { _singleSessionEnforced = enforced; }
56
59
61 void setIgnoreResetSessions(bool ignore) { _ignoreResetSessions = ignore; }
62
65 void setExpireSessionAfterBursts(int burstCount) { _expireSessionAfterBursts = burstCount; _burstsServed = 0; }
66
68 void setDropBurstPacketOnce(uint32_t offset) { _dropBurstPacketOffset = offset; _dropBurstPacketPending = true; }
69
72 void setReorderBurstPacketOnce(uint32_t offset) { _reorderBurstPacketOffset = offset; _reorderBurstPacketPending = true; }
73
75 int openFileROCount() const { return _openFileROCount; }
76
78 int readFileCount() const { return _readFileCount; }
79
81 int lastBurstReadRequestSize() const { return _lastBurstReadRequestSize; }
82
84 int lastReadFileRequestSize() const { return _lastReadFileRequestSize; }
85
87 void mavlinkMessageReceived(const mavlink_message_t &message);
88
89 void enableRandomDrops(bool enable) { _randomDropsEnabled = enable; }
90
92 QStringList uploadedFiles() const { return _uploadedFiles.keys(); }
93
95 QByteArray uploadedFileContents(const QString& remotePath) const { return _uploadedFiles.value(remotePath); }
96
98 void clearUploadedFiles() { _uploadedFiles.clear(); }
99
110
112 void setErrorMode(ErrorMode_t errMode) { _errMode = errMode; };
113
116 void setListDirectoryWithTimeSupported(bool supported) { _listDirectoryWithTimeSupported = supported; }
117
120 void setListDirectoryWithTimeNakError(MavlinkFTP::ErrorCode_t error) { _listDirectoryWithTimeNakError = error; }
121
123 void setLogDirEntriesWithTime(bool enabled) { _logDirEntriesWithTime = enabled; }
124
126 void setLogDirDotEntries(bool enabled) { _logDirDotEntries = enabled; }
127
138
140 static constexpr const size_t cFailureModes = std::size(MockLinkFTP::rgFailureModes);
141
142 static constexpr const char *sizeFilenamePrefix = "mocklink-size-";
143
146 static constexpr uint32_t kMockModificationTime = 1700000000;
147
148signals:
151
154
155private:
157 void _sendAck(uint8_t targetSystemId, uint8_t targetComponentId, uint16_t seqNumber, MavlinkFTP::OpCode_t reqOpCode);
158 void _sendNak(uint8_t targetSystemId, uint8_t targetComponentId, MavlinkFTP::ErrorCode_t error, uint16_t seqNumber, MavlinkFTP::OpCode_t reqOpCode);
159 void _sendNakErrno(uint8_t targetSystemId, uint8_t targetComponentId, uint8_t nakErrno, uint16_t seqNumber, MavlinkFTP::OpCode_t reqOpCode);
161 void _sendResponse(uint8_t targetSystemId, uint8_t targetComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
163 void _listCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber, bool withTime);
164 void _openCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
165 void _createFileCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
166 void _openFileWOCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
167 void _readCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
168 void _burstReadCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
169 void _removeFileCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
170 void _terminateCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
171 void _resetCommand(uint8_t senderSystemId, uint8_t senderComponentId, uint16_t seqNumber);
172 void _writeCommand(uint8_t senderSystemId, uint8_t senderComponentId, MavlinkFTP::Request *request, uint16_t seqNumber);
173 void _finalizeActiveUpload();
176 uint16_t _nextSeqNumber(uint16_t seqNumber) const;
177 static QString _createTestTempFile(int size);
178 QString _generateParamPck(bool withDefaults);
179 QString _logFileTempPath(const QString &name);
181 std::optional<QStringList> _logDirectoryEntries(const QString& subdir, bool withTime) const;
182 static QByteArray _generateLogFileContents(const QString &name, int size);
183
185 static void ensureNullTemination(MavlinkFTP::Request *request);
186
187 const uint8_t _systemIdServer;
188 const uint8_t _componentIdServer;
189 MockLink *_mockLink;
190
191 bool _lastReplyValid = false;
192 bool _randomDropsEnabled = false;
193 int _burstReadDelayMs = 0;
194 ErrorMode_t _errMode = errModeNone;
195 bool _listDirectoryWithTimeSupported = true;
196 MavlinkFTP::ErrorCode_t _listDirectoryWithTimeNakError = MavlinkFTP::kErrUnknownCommand;
197 bool _logDirEntriesWithTime = false;
198 bool _logDirDotEntries = false;
199 bool _paramPckEnabled = true;
200 bool _singleSessionEnforced = false;
201 bool _ignoreResetSessions = false;
202 int _expireSessionAfterBursts = 0;
203 int _burstsServed = 0;
204 uint32_t _dropBurstPacketOffset = 0;
205 bool _dropBurstPacketPending = false;
206 uint32_t _reorderBurstPacketOffset = 0;
207 bool _reorderBurstPacketPending = false;
208 int _openFileROCount = 0;
209 int _readFileCount = 0;
210 int _lastBurstReadRequestSize = -1;
211 int _lastReadFileRequestSize = -1;
212 mavlink_message_t _lastReply{};
213 QFile _currentFile;
214 QString _paramPckTempFile;
215 struct UploadSession {
216 bool active = false;
217 QString remotePath;
218 QByteArray buffer;
219
220 void reset() {
221 active = false;
222 remotePath.clear();
223 buffer.clear();
224 }
225 };
226 UploadSession _uploadSession;
227 QHash<QString, QByteArray> _uploadedFiles;
228 QStringList _fileList;
229 QList<LogFile> _logFiles;
230 QHash<QString, QString> _logFileTempPaths;
231 uint16_t _lastReplySequence = 0;
232
233 static constexpr uint8_t _sessionId = 1;
234};
Error error
struct __mavlink_message mavlink_message_t
ErrorCode_t
Error codes returned in Nak response PayloadHeader.data[0].
Definition MAVLinkFTP.h:62
@ kErrUnknownCommand
Unknown command opcode.
Definition MAVLinkFTP.h:70
Mock implementation of Mavlink FTP server.
Definition MockLinkFTP.h:18
void setParamPckEnabled(bool enabled)
When false, OpenFileRO of @PARAM/param.pck NAKs errno ENOENT, as PX4 without the virtual file does.
Definition MockLinkFTP.h:52
void setLogDirDotEntries(bool enabled)
When true, @MAV_LOG listings start with "D." and "D.." entries, as ArduPilot sends.
void enableRandomDrops(bool enable)
Definition MockLinkFTP.h:89
void resetCommandReceived()
You can connect to this signal to be notified when the server receives a Reset command.
void setFileList(const QStringList &fileList)
Definition MockLinkFTP.h:27
static constexpr uint32_t kMockModificationTime
void setReorderBurstPacketOnce(uint32_t offset)
Definition MockLinkFTP.h:72
void terminateCommandReceived()
You can connect to this signal to be notified when the server receives a Terminate command.
QList< LogFile > logFiles() const
Returns the log files served from the @MAV_LOG virtual directory.
Definition MockLinkFTP.h:41
void setLogFiles(const QList< LogFile > &logFiles)
void openStaleSessionForTest()
Opens a read session server-side without any client request, simulating a session left behind by a cr...
void setDropBurstPacketOnce(uint32_t offset)
Drops the burst data packet at the given file offset, once, to force a hole the client must fill.
Definition MockLinkFTP.h:68
void setSingleSessionEnforced(bool enforced)
When true, OpenFileRO NAKs kErrNoSessionsAvailable while a read session is already open,...
Definition MockLinkFTP.h:55
void setBurstReadDelayMs(int delayMs)
Definition MockLinkFTP.h:49
void setExpireSessionAfterBursts(int burstCount)
Definition MockLinkFTP.h:65
void setListDirectoryWithTimeSupported(bool supported)
static constexpr const char * sizeFilenamePrefix
void mavlinkMessageReceived(const mavlink_message_t &message)
Called to handle an FTP message.
QByteArray logFileContents(const QString &name) const
static constexpr const ErrorMode_t rgFailureModes[]
int readFileCount() const
Number of ReadFile (non-burst) requests received since construction.
Definition MockLinkFTP.h:78
ErrorMode_t
By calling setErrorMode with one of these modes you can cause the server to simulate an error.
@ errModeBadSequence
Return response with bad sequence number.
@ errModeNoSecondResponseAllowRetry
No response to subsequent request to initial command, error will be cleared after this so retry will ...
@ errModeNakSecondResponse
Nak subsequent request to initial command.
@ errModeNoResponse
No response to any request, client should eventually time out with no Ack.
@ errModeNone
No error, respond correctly.
@ errModeNoSecondResponse
No response to subsequent request to initial command.
@ errModeNakResponse
Nak all requests.
QStringList uploadedFiles() const
Returns the list of remote paths which have been uploaded in this session.
Definition MockLinkFTP.h:92
void setIgnoreResetSessions(bool ignore)
When true, ResetSessions requests get no reply.
Definition MockLinkFTP.h:61
int lastBurstReadRequestSize() const
hdr.size of the most recent BurstReadFile request, -1 if none received yet.
Definition MockLinkFTP.h:81
static constexpr const size_t cFailureModes
The number of ErrorModes in the rgFailureModes array.
void clearUploadedFiles()
Clears the stored uploaded file contents.
Definition MockLinkFTP.h:98
void setLogDirEntriesWithTime(bool enabled)
When true, kCmdListDirectoryWithTime directory entries under @MAV_LOG carry "\t0\t<mtime>",...
void setErrorMode(ErrorMode_t errMode)
Sets the error mode for command responses. This allows you to simulate various server errors.
void setListDirectoryWithTimeNakError(MavlinkFTP::ErrorCode_t error)
QByteArray uploadedFileContents(const QString &remotePath) const
Returns the contents of an uploaded file. Empty if the path is unknown.
Definition MockLinkFTP.h:95
int openFileROCount() const
Number of OpenFileRO requests acked since construction.
Definition MockLinkFTP.h:75
int lastReadFileRequestSize() const
hdr.size of the most recent ReadFile request, -1 if none received yet.
Definition MockLinkFTP.h:84
Describes a simulated onboard log file served from the @MAV_LOG virtual directory.
Definition MockLinkFTP.h:30
int size
File size in bytes.
Definition MockLinkFTP.h:32
QString name
File name, e.g. "log_1.ulg", or "<subdir>/log_1.ulg" to serve it from a subdirectory.
Definition MockLinkFTP.h:31
uint32_t mtime
Modification time (seconds since UNIX epoch UTC)
Definition MockLinkFTP.h:33