QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
FTPManager.h
Go to the documentation of this file.
1#pragma once
2
3#include "MAVLinkFTP.h"
4
5#include <QtCore/QObject>
6#include <QtCore/QDir>
7#include <QtCore/QFile>
8#include <QtCore/QTimer>
9class Vehicle;
10
11class FTPManager : public QObject
12{
13 Q_OBJECT
14
15 friend class Vehicle;
16
17public:
18 FTPManager(Vehicle* vehicle);
19
33 bool download(uint8_t fromCompId, const QString& fromURI, const QString& toDir, const QString& fileName="", bool checksize = true);
34
41 bool upload(uint8_t toCompId, const QString& toURI, const QString& fromFile);
42
49 bool listDirectory(uint8_t fromCompId, const QString& fromURI);
50
52 bool listDirectoryWithTimeUnsupported() const { return _listDirWithTimeSupport == WithTimeSupport_t::Unsupported; }
53
59 bool deleteFile(uint8_t fromCompId, const QString& fromURI);
60
63 void cancelDownload();
64
68
71 void cancelDelete();
72
75 void cancelUpload();
76
77 static constexpr const char* mavlinkFTPScheme = "mftp";
78
79signals:
80 void downloadComplete (const QString& file, const QString& errorMsg);
81 void uploadComplete (const QString& file, const QString& errorMsg);
82 void listDirectoryComplete (const QStringList& dirList, const QString& errorMsg);
83 void deleteComplete (const QString& file, const QString& errorMsg);
84
87 void commandProgress(float value);
88
89private slots:
90 void _ackOrNakTimeout(void);
91
92private:
93 typedef void (FTPManager::*StateBeginFn) (void);
94 typedef void (FTPManager::*StateAckNakFn) (const MavlinkFTP::Request* ackOrNak);
95 typedef void (FTPManager::*StateTimeoutFn) (void);
96
97 struct StateFunctions_t {
98 StateBeginFn beginFn;
99 StateAckNakFn ackNakFn;
100 StateTimeoutFn timeoutFn;
101 };
102
103 struct MissingData_t {
104 uint32_t offset;
105 uint32_t cBytesMissing;
106 };
107
108 struct DownloadState_t {
109 uint8_t sessionId;
110 uint32_t expectedOffset;
111 uint32_t bytesWritten;
112 QList<MissingData_t> rgMissingData;
113 QString fullPathOnVehicle;
114 QDir toDir;
115 QString fileName;
116 uint32_t fileSize;
117 QFile file;
118 int retryCount;
119 bool checksize;
120
121 bool inProgress() const { return fileSize > 0; }
122
123 void reset() {
124 sessionId = 0;
125 expectedOffset = 0;
126 bytesWritten = 0;
127 retryCount = 0;
128 fileSize = 0;
129 fullPathOnVehicle.clear();
130 fileName.clear();
131 rgMissingData.clear();
132 file.close();
133 }
134 };
135
136 struct ListDirectoryState_t {
137 uint8_t sessionId;
138 uint32_t expectedOffset;
139 QString fullPathOnVehicle;
140 QStringList rgDirectoryList;
141 int retryCount;
142 MavlinkFTP::OpCode_t opCode;
143
144 bool inProgress() const { return !fullPathOnVehicle.isEmpty(); }
145
146 void reset() {
147 sessionId = 0;
148 expectedOffset = 0;
149 fullPathOnVehicle.clear();
150 rgDirectoryList.clear();
151 retryCount = 0;
153 }
154 };
155
158 enum class WithTimeSupport_t { Unknown, Supported, Unsupported };
159
160 struct DeleteFileState_t {
161 QString fullPathOnVehicle;
162 int retryCount = 0;
163
164 bool inProgress() const { return !fullPathOnVehicle.isEmpty(); }
165
166 void reset() {
167 fullPathOnVehicle.clear();
168 retryCount = 0;
169 }
170 };
171
172 struct UploadState_t {
173 uint8_t sessionId;
174 uint32_t totalBytesSent;
175 uint32_t fileSize;
176 uint32_t lastChunkSize;
177 QFile file;
178 QString fullPathOnVehicle;
179 QString localFilePath;
180 int retryCount;
181 bool cancelled;
182
183 bool inProgress() const { return file.isOpen(); }
184
185 void reset() {
186 sessionId = 0;
187 totalBytesSent = 0;
188 fileSize = 0;
189 lastChunkSize = 0;
190 retryCount = 0;
191 cancelled = false;
192 fullPathOnVehicle.clear();
193 localFilePath.clear();
194 file.close();
195 }
196 };
197
198 void _mavlinkMessageReceived (const mavlink_message_t& message);
199 void _startStateMachine (void);
200 void _advanceStateMachine (void);
201 void _listDirectoryBegin (void);
202 void _listDirectoryAckOrNak (const MavlinkFTP::Request* ackOrNak);
203 void _listDirectoryTimeout (void);
204 void _openFileROBegin (void);
205 void _openFileROAckOrNak (const MavlinkFTP::Request* ackOrNak);
206 void _openFileROTimeout (void);
207 void _burstReadFileBegin (void);
208 void _burstReadFileAckOrNak (const MavlinkFTP::Request* ackOrNak);
209 void _burstReadFileTimeout (void);
210 void _fillMissingBlocksBegin (void);
211 void _fillMissingBlocksAckOrNak (const MavlinkFTP::Request* ackOrNak);
212 void _fillMissingBlocksTimeout (void);
213 void _resetSessionsBegin (void);
214 void _resetSessionsAckOrNak (const MavlinkFTP::Request* ackOrNak);
215 void _resetSessionsTimeout (void);
216 QString _errorMsgFromNak (const MavlinkFTP::Request* nak);
217 void _sendRequestExpectAck (MavlinkFTP::Request* request);
218 void _downloadCompleteNoError (void) { _downloadComplete(QString()); }
219 void _downloadComplete (const QString& errorMsg);
220 void _fillRequestDataWithString(MavlinkFTP::Request* request, const QString& str);
221 void _fillMissingBlocksWorker (bool firstRequest);
222 void _burstReadFileWorker (bool firstRequest);
223 void _listDirectoryWorker (bool firstRequest);
224 bool _parseURI (uint8_t fromCompId, const QString& uri, QString& parsedURI, uint8_t& compId);
225 void _listDirectoryCompleteNoError(void) { _listDirectoryComplete(QString()); }
226 void _listDirectoryComplete (const QString& errorMsg);
227 void _deleteFileBegin (void);
228 void _deleteFileAckOrNak (const MavlinkFTP::Request* ackOrNak);
229 void _deleteFileTimeout (void);
230 void _deleteCompleteNoError (void) { _deleteComplete(QString()); }
231 void _deleteComplete (const QString& errorMsg);
232
233 void _createFileBegin (void);
234 void _createFileAckOrNak (const MavlinkFTP::Request* ackOrNak);
235 void _createFileTimeout (void);
236 void _writeFileBegin (void);
237 void _writeFileAckOrNak (const MavlinkFTP::Request* ackOrNak);
238 void _writeFileTimeout (void);
239 void _writeFileWorker (bool firstRequest);
240 void _uploadFinalize (void);
241 void _uploadComplete (const QString& errorMsg);
242 void _terminateUploadSessionBegin(void);
243 void _terminateUploadSessionAckOrNak(const MavlinkFTP::Request* ackOrNak);
244 void _terminateUploadSessionTimeout(void);
245
246 void _terminateSessionBegin (void);
247 void _terminateSessionAckOrNak (const MavlinkFTP::Request* ackOrNak);
248 void _terminateSessionTimeout (void);
249 void _terminateComplete (void);
250
251 Vehicle* _vehicle;
252 uint8_t _ftpCompId = MAV_COMP_ID_AUTOPILOT1;
253 QList<StateFunctions_t> _rgStateMachine;
254 DownloadState_t _downloadState;
255 ListDirectoryState_t _listDirectoryState;
256 DeleteFileState_t _deleteState;
257 UploadState_t _uploadState;
258 QTimer _ackOrNakTimeoutTimer;
259 int _currentStateMachineIndex = -1;
260 uint16_t _expectedIncomingSeqNumber = 0;
261 WithTimeSupport_t _listDirWithTimeSupport = WithTimeSupport_t::Unknown;
262
263 static const int _ackOrNakTimeoutMsecs = 1000;
264 static const int _maxRetry = 3;
265
266public:
268 static constexpr int kTestAckTimeoutMs = 10;
270 static constexpr int kTestOperationMaxWaitMs = 5000;
271};
struct __mavlink_message mavlink_message_t
bool listDirectoryWithTimeUnsupported() const
true when the vehicle NAK'ed kCmdListDirectoryWithTime, i.e. directory listings carry no modification...
Definition FTPManager.h:52
static constexpr int kTestAckTimeoutMs
Ack timeout used in unit tests (much shorter for faster tests)
Definition FTPManager.h:268
void cancelDownload()
bool listDirectory(uint8_t fromCompId, const QString &fromURI)
bool deleteFile(uint8_t fromCompId, const QString &fromURI)
bool upload(uint8_t toCompId, const QString &toURI, const QString &fromFile)
Definition FTPManager.cc:85
static constexpr const char * mavlinkFTPScheme
Definition FTPManager.h:77
void uploadComplete(const QString &file, const QString &errorMsg)
void cancelUpload()
static constexpr int kTestOperationMaxWaitMs
Maximum wait time for FTP operations in unit tests (generous for multi-packet transfers)
Definition FTPManager.h:270
void commandProgress(float value)
void downloadComplete(const QString &file, const QString &errorMsg)
void cancelListDirectory()
void deleteComplete(const QString &file, const QString &errorMsg)
void cancelDelete()
bool download(uint8_t fromCompId, const QString &fromURI, const QString &toDir, const QString &fileName="", bool checksize=true)
Definition FTPManager.cc:30
void listDirectoryComplete(const QStringList &dirList, const QString &errorMsg)
@ kCmdListDirectory
List files in <path> from <offset>
Definition MAVLinkFTP.h:42
@ Unsupported
Definition ADSB.h:28