Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
4b861414
Commit
4b861414
authored
Jun 26, 2014
by
Lorenz Meier
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #725 from DonLakeFlyer/mavlink-ftp
Mavlink FTP implementation List command
parents
b943c494
81452e02
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
808 additions
and
121 deletions
+808
-121
qgroundcontrol.pro
qgroundcontrol.pro
+7
-2
MockMavlinkFileServer.cc
src/qgcunittest/MockMavlinkFileServer.cc
+148
-0
MockMavlinkFileServer.h
src/qgcunittest/MockMavlinkFileServer.h
+52
-0
MockMavlinkInterface.cc
src/qgcunittest/MockMavlinkInterface.cc
+9
-0
MockMavlinkInterface.h
src/qgcunittest/MockMavlinkInterface.h
+44
-0
MockUAS.cc
src/qgcunittest/MockUAS.cc
+13
-1
MockUAS.h
src/qgcunittest/MockUAS.h
+11
-4
QGCUASFileManagerTest.cc
src/qgcunittest/QGCUASFileManagerTest.cc
+156
-0
QGCUASFileManagerTest.h
src/qgcunittest/QGCUASFileManagerTest.h
+92
-0
QGCUASFileManager.cc
src/uas/QGCUASFileManager.cc
+188
-87
QGCUASFileManager.h
src/uas/QGCUASFileManager.h
+78
-27
UAS.cc
src/uas/UAS.cc
+5
-0
MainWindow.cc
src/ui/MainWindow.cc
+4
-0
QGCUASFileView.cc
src/ui/QGCUASFileView.cc
+1
-0
No files found.
qgroundcontrol.pro
View file @
4b861414
...
...
@@ -186,16 +186,21 @@ DebugBuild {
src
/
qgcunittest
/
MockUASManager
.
h
\
src
/
qgcunittest
/
MockUAS
.
h
\
src
/
qgcunittest
/
MockQGCUASParamManager
.
h
\
src
/
qgcunittest
/
MockMavlinkInterface
.
h
\
src
/
qgcunittest
/
MockMavlinkFileServer
.
h
\
src
/
qgcunittest
/
MultiSignalSpy
.
h
\
src
/
qgcunittest
/
FlightModeConfigTest
.
h
src
/
qgcunittest
/
FlightModeConfigTest
.
h
\
src
/
qgcunittest
/
QGCUASFileManagerTest
.
h
SOURCES
+=
\
src
/
qgcunittest
/
UASUnitTest
.
cc
\
src
/
qgcunittest
/
MockUASManager
.
cc
\
src
/
qgcunittest
/
MockUAS
.
cc
\
src
/
qgcunittest
/
MockQGCUASParamManager
.
cc
\
src
/
qgcunittest
/
MockMavlinkFileServer
.
cc
\
src
/
qgcunittest
/
MultiSignalSpy
.
cc
\
src
/
qgcunittest
/
FlightModeConfigTest
.
cc
src
/
qgcunittest
/
FlightModeConfigTest
.
cc
\
src
/
qgcunittest
/
QGCUASFileManagerTest
.
cc
}
#
...
...
src/qgcunittest/MockMavlinkFileServer.cc
0 → 100644
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "MockMavlinkFileServer.h"
void
MockMavlinkFileServer
::
sendMessage
(
mavlink_message_t
message
)
{
QGCUASFileManager
::
Request
ackResponse
;
QString
path
;
Q_ASSERT
(
message
.
msgid
==
MAVLINK_MSG_ID_ENCAPSULATED_DATA
);
mavlink_encapsulated_data_t
requestEncapsulatedData
;
mavlink_msg_encapsulated_data_decode
(
&
message
,
&
requestEncapsulatedData
);
QGCUASFileManager
::
Request
*
request
=
(
QGCUASFileManager
::
Request
*
)
&
requestEncapsulatedData
.
data
[
0
];
// Validate CRC
if
(
request
->
hdr
.
crc32
!=
QGCUASFileManager
::
crc32
(
request
))
{
_sendNak
(
QGCUASFileManager
::
kErrCrc
);
}
switch
(
request
->
hdr
.
opcode
)
{
case
QGCUASFileManager
:
:
kCmdTestNoAck
:
// ignored, ack not sent back, for testing only
break
;
case
QGCUASFileManager
:
:
kCmdReset
:
// terminates all sessions
// Fall through to send back Ack
case
QGCUASFileManager
:
:
kCmdNone
:
// ignored, always acked
ackResponse
.
hdr
.
magic
=
'f'
;
ackResponse
.
hdr
.
opcode
=
QGCUASFileManager
::
kRspAck
;
ackResponse
.
hdr
.
session
=
0
;
ackResponse
.
hdr
.
crc32
=
0
;
ackResponse
.
hdr
.
size
=
0
;
_emitResponse
(
&
ackResponse
);
break
;
case
QGCUASFileManager
:
:
kCmdList
:
// We only support root path
path
=
(
char
*
)
&
request
->
data
[
0
];
if
(
!
path
.
isEmpty
()
&&
path
!=
"/"
)
{
_sendNak
(
QGCUASFileManager
::
kErrNotDir
);
break
;
}
if
(
request
->
hdr
.
offset
>
(
uint32_t
)
_fileList
.
size
())
{
_sendNak
(
QGCUASFileManager
::
kErrEOF
);
break
;
}
ackResponse
.
hdr
.
magic
=
'f'
;
ackResponse
.
hdr
.
opcode
=
QGCUASFileManager
::
kRspAck
;
ackResponse
.
hdr
.
session
=
0
;
ackResponse
.
hdr
.
size
=
0
;
if
(
request
->
hdr
.
offset
==
0
)
{
// Requesting first batch of file names
Q_ASSERT
(
_fileList
.
size
());
char
*
bufPtr
=
(
char
*
)
&
ackResponse
.
data
[
0
];
for
(
int
i
=
0
;
i
<
_fileList
.
size
();
i
++
)
{
const
char
*
filename
=
_fileList
[
i
].
toStdString
().
c_str
();
size_t
cchFilename
=
strlen
(
filename
);
strcpy
(
bufPtr
,
filename
);
ackResponse
.
hdr
.
size
+=
cchFilename
+
1
;
bufPtr
+=
cchFilename
+
1
;
}
// Final double termination
*
bufPtr
=
0
;
ackResponse
.
hdr
.
size
++
;
}
else
{
// All filenames fit in first ack, send final null terminated ack
ackResponse
.
data
[
0
]
=
0
;
ackResponse
.
hdr
.
size
=
1
;
}
_emitResponse
(
&
ackResponse
);
break
;
// Remainder of commands are NYI
case
QGCUASFileManager
:
:
kCmdTerminate
:
// releases sessionID, closes file
case
QGCUASFileManager
:
:
kCmdOpen
:
// opens <path> for reading, returns <session>
case
QGCUASFileManager
:
:
kCmdRead
:
// reads <size> bytes from <offset> in <session>
case
QGCUASFileManager
:
:
kCmdCreate
:
// creates <path> for writing, returns <session>
case
QGCUASFileManager
:
:
kCmdWrite
:
// appends <size> bytes at <offset> in <session>
case
QGCUASFileManager
:
:
kCmdRemove
:
// remove file (only if created by server?)
default:
// nack for all NYI opcodes
_sendNak
(
QGCUASFileManager
::
kErrUnknownCommand
);
break
;
}
}
void
MockMavlinkFileServer
::
_sendNak
(
QGCUASFileManager
::
ErrorCode
error
)
{
QGCUASFileManager
::
Request
nakResponse
;
nakResponse
.
hdr
.
magic
=
'f'
;
nakResponse
.
hdr
.
opcode
=
QGCUASFileManager
::
kRspNak
;
nakResponse
.
hdr
.
session
=
0
;
nakResponse
.
hdr
.
size
=
sizeof
(
nakResponse
.
data
[
0
]);
nakResponse
.
data
[
0
]
=
error
;
_emitResponse
(
&
nakResponse
);
}
void
MockMavlinkFileServer
::
_emitResponse
(
QGCUASFileManager
::
Request
*
request
)
{
mavlink_message_t
mavlinkMessage
;
request
->
hdr
.
crc32
=
QGCUASFileManager
::
crc32
(
request
);
mavlink_msg_encapsulated_data_pack
(
250
,
0
,
&
mavlinkMessage
,
0
/*_encdata_seq*/
,
(
uint8_t
*
)
request
);
emit
messageReceived
(
NULL
,
mavlinkMessage
);
}
\ No newline at end of file
src/qgcunittest/MockMavlinkFileServer.h
0 → 100644
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef MOCKMAVLINKFILESERVER_H
#define MOCKMAVLINKFILESERVER_H
#include "MockMavlinkInterface.h"
#include "QGCUASFileManager.h"
#include <QStringList>
class
MockMavlinkFileServer
:
public
MockMavlinkInterface
{
Q_OBJECT
public:
MockMavlinkFileServer
(
void
)
{
};
void
setFileList
(
QStringList
&
fileList
)
{
_fileList
=
fileList
;
}
// From MockMavlinkInterface
virtual
void
sendMessage
(
mavlink_message_t
message
);
private:
void
_sendNak
(
QGCUASFileManager
::
ErrorCode
error
);
void
_emitResponse
(
QGCUASFileManager
::
Request
*
request
);
QStringList
_fileList
;
};
#endif
src/qgcunittest/MockMavlinkInterface.cc
0 → 100644
View file @
4b861414
//
// MockMavlinkInterface.cc
// QGroundControl
//
// Created by Donald Gagne on 6/19/14.
// Copyright (c) 2014 Donald Gagne. All rights reserved.
//
#include "MockMavlinkInterface.h"
src/qgcunittest/MockMavlinkInterface.h
0 → 100644
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include <QObject>
#include "QGCMAVLink.h"
#include "LinkInterface.h"
#ifndef MOCKMAVLINKINTERFACE_H
#define MOCKMAVLINKINTERFACE_H
class
MockMavlinkInterface
:
public
QObject
{
Q_OBJECT
public:
virtual
void
sendMessage
(
mavlink_message_t
message
)
=
0
;
signals:
// link argument will always be NULL
void
messageReceived
(
LinkInterface
*
link
,
mavlink_message_t
message
);
};
#endif
src/qgcunittest/MockUAS.cc
View file @
4b861414
...
...
@@ -27,7 +27,8 @@ QString MockUAS::_bogusStaticString;
MockUAS
::
MockUAS
(
void
)
:
_systemType
(
MAV_TYPE_QUADROTOR
),
_systemId
(
1
)
_systemId
(
1
),
_mavlinkPlugin
(
NULL
)
{
}
...
...
@@ -41,4 +42,15 @@ void MockUAS::setMockParametersAndSignal(MockQGCUASParamManager::ParamMap_t& map
i
.
next
();
emit
parameterChanged
(
_systemId
,
0
,
i
.
key
(),
i
.
value
());
}
}
void
MockUAS
::
sendMessage
(
mavlink_message_t
message
)
{
Q_UNUSED
(
link
);
if
(
!
_mavlinkPlugin
)
{
Q_ASSERT
(
false
);
}
_mavlinkPlugin
->
sendMessage
(
message
);
}
\ No newline at end of file
src/qgcunittest/MockUAS.h
View file @
4b861414
...
...
@@ -26,6 +26,7 @@
#include "UASInterface.h"
#include "MockQGCUASParamManager.h"
#include "MockMavlinkInterface.h"
#include <limits>
...
...
@@ -50,6 +51,9 @@ public:
virtual
int
getUASID
(
void
)
const
{
return
_systemId
;
}
virtual
QGCUASParamManagerInterface
*
getParamManager
()
{
return
&
_paramManager
;
};
// sendMessage is only supported if a mavlink plugin is installed.
virtual
void
sendMessage
(
mavlink_message_t
message
);
public:
// MockUAS methods
MockUAS
(
void
);
...
...
@@ -63,12 +67,15 @@ public:
/// allows you to simulate parameter input and validate parameter setting
MockQGCUASParamManager
*
getMockQGCUASParamManager
(
void
)
{
return
&
_paramManager
;
}
/// Sets the parameter map into the mock QGCUASParamManager and signals parameterChanged for
///
@brief
Sets the parameter map into the mock QGCUASParamManager and signals parameterChanged for
/// each param
void
setMockParametersAndSignal
(
MockQGCUASParamManager
::
ParamMap_t
&
map
);
void
emitRemoteControlChannelRawChanged
(
int
channel
,
float
raw
)
{
emit
remoteControlChannelRawChanged
(
channel
,
raw
);
}
/// @brief Installs a mavlink plugin. Only a single mavlink plugin is supported at a time.
void
setMockMavlinkPlugin
(
MockMavlinkInterface
*
mavlinkPlugin
)
{
_mavlinkPlugin
=
mavlinkPlugin
;
};
public:
// Unimplemented UASInterface overrides
virtual
QString
getUASName
()
const
{
Q_ASSERT
(
false
);
return
_bogusString
;
};
...
...
@@ -112,9 +119,7 @@ public:
virtual
QGCUASFileManager
*
getFileManager
()
{
Q_ASSERT
(
false
);
return
NULL
;
}
/** @brief Send a message over this link (to this or to all UAS on this link) */
virtual
void
sendMessage
(
LinkInterface
*
link
,
mavlink_message_t
message
){
Q_ASSERT
(
false
);}
/** @brief Send a message over all links this UAS can be reached with (!= all links) */
virtual
void
sendMessage
(
mavlink_message_t
message
)
{
Q_ASSERT
(
false
);}
virtual
void
sendMessage
(
LinkInterface
*
link
,
mavlink_message_t
message
){
Q_UNUSED
(
link
);
Q_UNUSED
(
message
);
Q_ASSERT
(
false
);
}
virtual
QString
getAutopilotTypeName
()
{
Q_ASSERT
(
false
);
return
_bogusString
;
};
virtual
void
setAutopilotType
(
int
apType
)
{
Q_UNUSED
(
apType
);
Q_ASSERT
(
false
);
};
virtual
QMap
<
int
,
QString
>
getComponents
()
{
Q_ASSERT
(
false
);
return
_bogusMapIntQString
;
};
...
...
@@ -182,6 +187,8 @@ private:
int
_systemId
;
MockQGCUASParamManager
_paramManager
;
MockMavlinkInterface
*
_mavlinkPlugin
;
///< Mock Mavlink plugin, NULL for none
// Bogus variables used for return types of NYI methods
QString
_bogusString
;
...
...
src/qgcunittest/QGCUASFileManagerTest.cc
0 → 100644
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "QGCUASFileManagerTest.h"
/// @file
/// @brief QGCUASFileManager unit test
///
/// @author Don Gagne <don@thegagnes.com>
QGCUASFileManagerUnitTest
::
QGCUASFileManagerUnitTest
(
void
)
:
_fileManager
(
NULL
),
_multiSpy
(
NULL
)
{
}
// Called once before all test cases are run
void
QGCUASFileManagerUnitTest
::
initTestCase
(
void
)
{
_mockUAS
.
setMockMavlinkPlugin
(
&
_mockFileServer
);
}
// Called before every test case
void
QGCUASFileManagerUnitTest
::
init
(
void
)
{
Q_ASSERT
(
_multiSpy
==
NULL
);
_fileManager
=
new
QGCUASFileManager
(
NULL
,
&
_mockUAS
);
Q_CHECK_PTR
(
_fileManager
);
bool
connected
=
connect
(
&
_mockFileServer
,
SIGNAL
(
messageReceived
(
LinkInterface
*
,
mavlink_message_t
)),
_fileManager
,
SLOT
(
receiveMessage
(
LinkInterface
*
,
mavlink_message_t
)));
Q_ASSERT
(
connected
);
connected
=
connect
(
_fileManager
,
SIGNAL
(
statusMessage
(
const
QString
&
)),
this
,
SLOT
(
statusMessage
(
const
QString
&
)));
Q_ASSERT
(
connected
);
_rgSignals
[
statusMessageSignalIndex
]
=
SIGNAL
(
statusMessage
(
const
QString
&
));
_rgSignals
[
errorMessageSignalIndex
]
=
SIGNAL
(
errorMessage
(
const
QString
&
));
_rgSignals
[
resetStatusMessagesSignalIndex
]
=
SIGNAL
(
resetStatusMessages
(
void
));
_multiSpy
=
new
MultiSignalSpy
();
Q_CHECK_PTR
(
_multiSpy
);
QCOMPARE
(
_multiSpy
->
init
(
_fileManager
,
_rgSignals
,
_cSignals
),
true
);
}
// Called after every test case
void
QGCUASFileManagerUnitTest
::
cleanup
(
void
)
{
Q_ASSERT
(
_multiSpy
);
Q_ASSERT
(
_fileManager
);
delete
_fileManager
;
delete
_multiSpy
;
_fileManager
=
NULL
;
_multiSpy
=
NULL
;
}
/// @brief Connected to QGCUASFileManager statusMessage signal in order to catch list command output
void
QGCUASFileManagerUnitTest
::
statusMessage
(
const
QString
&
msg
)
{
// Keep a list of all names received so we can test it for correctness
_fileListReceived
+=
msg
;
}
void
QGCUASFileManagerUnitTest
::
_ackTest
(
void
)
{
Q_ASSERT
(
_fileManager
);
Q_ASSERT
(
_multiSpy
);
Q_ASSERT
(
_multiSpy
->
checkNoSignals
()
==
true
);
// If the file manager doesn't receive an ack it will timeout and emit an error. So make sure
// we don't get any error signals.
QVERIFY
(
_fileManager
->
_sendCmdTestAck
());
QVERIFY
(
_multiSpy
->
checkNoSignals
());
}
void
QGCUASFileManagerUnitTest
::
_noAckTest
(
void
)
{
Q_ASSERT
(
_fileManager
);
Q_ASSERT
(
_multiSpy
);
Q_ASSERT
(
_multiSpy
->
checkNoSignals
()
==
true
);
// This should not get the ack back and timeout.
QVERIFY
(
_fileManager
->
_sendCmdTestNoAck
());
QTest
::
qWait
(
2000
);
// Let the file manager timeout, magic number 2 secs must be larger than file manager ack timeout
QCOMPARE
(
_multiSpy
->
checkOnlySignalByMask
(
errorMessageSignalMask
),
true
);
}
void
QGCUASFileManagerUnitTest
::
_resetTest
(
void
)
{
Q_ASSERT
(
_fileManager
);
Q_ASSERT
(
_multiSpy
);
Q_ASSERT
(
_multiSpy
->
checkNoSignals
()
==
true
);
// Send a reset command
// We should not get any signals back from this
QVERIFY
(
_fileManager
->
_sendCmdReset
());
QVERIFY
(
_multiSpy
->
checkNoSignals
());
}
void
QGCUASFileManagerUnitTest
::
_listTest
(
void
)
{
Q_ASSERT
(
_fileManager
);
Q_ASSERT
(
_multiSpy
);
Q_ASSERT
(
_multiSpy
->
checkNoSignals
()
==
true
);
// Send a bogus path
// We should get a single resetStatusMessages signal
// We should get a single errorMessage signal
_fileManager
->
listRecursively
(
"/bogus"
);
QCOMPARE
(
_multiSpy
->
checkOnlySignalByMask
(
errorMessageSignalMask
|
resetStatusMessagesSignalMask
),
true
);
_multiSpy
->
clearAllSignals
();
// Send a list command at the root of the directory tree
// We should get back a single resetStatusMessages signal
// We should not get back an errorMessage signal
// We should get back one or more statusMessage signals
// The returned list should match out inputs
QStringList
fileList
;
fileList
<<
"Ddir"
<<
"Ffoo"
<<
"Fbar"
;
_mockFileServer
.
setFileList
(
fileList
);
QStringList
fileListExpected
;
fileListExpected
<<
"dir/"
<<
"foo"
<<
"bar"
;
_fileListReceived
.
clear
();
_fileManager
->
listRecursively
(
"/"
);
QCOMPARE
(
_multiSpy
->
checkSignalByMask
(
resetStatusMessagesSignalMask
),
true
);
// We should be told to reset status messages
QCOMPARE
(
_multiSpy
->
checkNoSignalByMask
(
errorMessageSignalMask
),
true
);
// We should not get an error signals
QVERIFY
(
_fileListReceived
==
fileListExpected
);
}
src/qgcunittest/QGCUASFileManagerTest.h
0 → 100644
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCUASFILEMANAGERTEST_H
#define QGCUASFILEMANAGERTEST_H
#include <QObject>
#include <QtTest/QtTest>
#include "AutoTest.h"
#include "MockUAS.h"
#include "MockMavlinkFileServer.h"
#include "QGCUASFileManager.h"
#include "MultiSignalSpy.h"
/// @file
/// @brief QGCUASFileManager unit test
///
/// @author Don Gagne <don@thegagnes.com>
class
QGCUASFileManagerUnitTest
:
public
QObject
{
Q_OBJECT
public:
QGCUASFileManagerUnitTest
(
void
);
private
slots
:
// Test case initialization
void
initTestCase
(
void
);
void
init
(
void
);
void
cleanup
(
void
);
// Test cases
void
_ackTest
(
void
);
void
_noAckTest
(
void
);
void
_resetTest
(
void
);
void
_listTest
(
void
);
// Connected to QGCUASFileManager statusMessage signal
void
statusMessage
(
const
QString
&
);
private:
enum
{
statusMessageSignalIndex
=
0
,
errorMessageSignalIndex
,
resetStatusMessagesSignalIndex
,
maxSignalIndex
};
enum
{
statusMessageSignalMask
=
1
<<
statusMessageSignalIndex
,
errorMessageSignalMask
=
1
<<
errorMessageSignalIndex
,
resetStatusMessagesSignalMask
=
1
<<
resetStatusMessagesSignalIndex
,
};
MockUAS
_mockUAS
;
MockMavlinkFileServer
_mockFileServer
;
QGCUASFileManager
*
_fileManager
;
MultiSignalSpy
*
_multiSpy
;
static
const
size_t
_cSignals
=
maxSignalIndex
;
const
char
*
_rgSignals
[
_cSignals
];
QStringList
_fileListReceived
;
};
DECLARE_TEST
(
QGCUASFileManagerUnitTest
)
#endif
src/uas/QGCUASFileManager.cc
View file @
4b861414
This diff is collapsed.
Click to expand it.
src/uas/QGCUASFileManager.h
View file @
4b861414
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCUASFILEMANAGER_H
#define QGCUASFILEMANAGER_H
#include <QObject>
#include "UASInterface.h"
class
QGCUASFileManager
:
public
QObject
...
...
@@ -9,17 +33,22 @@ class QGCUASFileManager : public QObject
Q_OBJECT
public:
QGCUASFileManager
(
QObject
*
parent
,
UASInterface
*
uas
);
/// These methods are only used for testing purposes.
bool
_sendCmdTestAck
(
void
)
{
return
_sendOpcodeOnlyCmd
(
kCmdNone
,
kCOAck
);
};
bool
_sendCmdTestNoAck
(
void
)
{
return
_sendOpcodeOnlyCmd
(
kCmdTestNoAck
,
kCOAck
);
};
bool
_sendCmdReset
(
void
)
{
return
_sendOpcodeOnlyCmd
(
kCmdReset
,
kCOAck
);
};
signals:
void
statusMessage
(
const
QString
&
msg
);
void
resetStatusMessages
();
void
errorMessage
(
const
QString
&
ms
);
public
slots
:
void
receiveMessage
(
LinkInterface
*
link
,
mavlink_message_t
message
);
void
nothingMessage
();
void
listRecursively
(
const
QString
&
from
);
void
downloadPath
(
const
QString
&
from
,
const
QString
&
to
);
// void timedOut();
protected:
struct
RequestHeader
...
...
@@ -30,23 +59,32 @@ protected:
uint8_t
size
;
uint32_t
crc32
;
uint32_t
offset
;
uint8_t
data
[];
};
struct
Request
{
struct
RequestHeader
hdr
;
// The entire Request must fit into the data member of the mavlink_encapsulated_data_t structure. We use as many leftover bytes
// after we use up space for the RequestHeader for the data portion of the Request.
uint8_t
data
[
sizeof
(((
mavlink_encapsulated_data_t
*
)
0
)
->
data
)
-
sizeof
(
RequestHeader
)];
};
enum
Opcode
{
kCmdNone
,
// ignored, always acked
kCmdNone
,
// ignored, always acked
kCmdTerminate
,
// releases sessionID, closes file
kCmdReset
,
// terminates all sessions
kCmdList
,
// list files in <path> from <offset>
kCmdOpen
,
// opens <path> for reading, returns <session>
kCmdRead
,
// reads <size> bytes from <offset> in <session>
kCmdCreate
,
// creates <path> for writing, returns <session>
kCmdWrite
,
// appends <size> bytes at <offset> in <session>
kCmdRemove
,
// remove file (only if created by server?)
kCmdReset
,
// terminates all sessions
kCmdList
,
// list files in <path> from <offset>
kCmdOpen
,
// opens <path> for reading, returns <session>
kCmdRead
,
// reads <size> bytes from <offset> in <session>
kCmdCreate
,
// creates <path> for writing, returns <session>
kCmdWrite
,
// appends <size> bytes at <offset> in <session>
kCmdRemove
,
// remove file (only if created by server?)
kRspAck
,
kRspNak
kRspNak
,
kCmdTestNoAck
,
// ignored, ack not sent back, for testing only, should timeout waiting for ack
};
enum
ErrorCode
...
...
@@ -61,36 +99,49 @@ protected:
kErrNotAppend
,
kErrTooBig
,
kErrIO
,
kErrPerm
kErrPerm
,
kErrUnknownCommand
,
kErrCrc
};
enum
OperationState
{
kCOIdle
,
// not doing anything
kCOAck
,
// waiting for an Ack
kCOList
,
// waiting for a List response
};
OperationState
_current_operation
;
unsigned
_retry_counter
;
UASInterface
*
_mav
;
quint16
_encdata_seq
;
unsigned
_session_id
;
// session ID for current session
unsigned
_list_offset
;
// offset for the current List operation
QString
_list_path
;
// path for the current List operation
void
sendTerminate
();
void
sendReset
();
protected
slots
:
void
_ackTimeout
(
void
);
protected:
bool
_sendOpcodeOnlyCmd
(
uint8_t
opcode
,
OperationState
newOpState
);
void
_setupAckTimeout
(
void
);
void
_clearAckTimeout
(
void
);
void
_emitErrorMessage
(
const
QString
&
msg
);
void
_sendRequest
(
Request
*
request
);
void
sendList
();
void
listDecode
(
const
uint8_t
*
data
,
unsigned
len
);
static
quint32
crc32
(
const
uint8_t
*
src
,
unsigned
len
,
unsigned
state
);
static
quint32
crc32
(
Request
*
request
,
unsigned
state
=
0
);
static
QString
errorString
(
uint8_t
errorCode
);
OperationState
_currentOperation
;
///> Current operation of state machine
QTimer
_ackTimer
;
///> Used to signal a timeout waiting for an ack
static
const
int
_ackTimerTimeoutMsecs
=
1000
;
///> Timeout in msecs for ack timer
UASInterface
*
_mav
;
quint16
_encdata_seq
;
unsigned
_listOffset
;
// offset for the current List operation
QString
_listPath
;
// path for the current List operation
// We give MockMavlinkFileServer friend access so that it can use the data structures and opcodes
// to build a mock mavlink file server for testing.
friend
class
MockMavlinkFileServer
;
};
#endif // QGCUASFILEMANAGER_H
src/uas/UAS.cc
View file @
4b861414
...
...
@@ -149,6 +149,8 @@ UAS::UAS(MAVLinkProtocol* protocol, QThread* thread, int id) : UASInterface(),
pitch
(
0.0
),
yaw
(
0.0
),
imagePackets
(
0
),
// We must initialize to 0, otherwise extended data packets maybe incorrectly thought to be images
blockHomePositionChanges
(
false
),
receivedMode
(
false
),
...
...
@@ -1321,6 +1323,7 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
// NO VALID TRANSACTION - ABORT
// Restart statemachine
imagePacketsArrived
=
0
;
break
;
}
for
(
int
i
=
0
;
i
<
imagePayload
;
++
i
)
...
...
@@ -1337,6 +1340,8 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message)
if
((
imagePacketsArrived
>=
imagePackets
))
{
// Restart statemachine
imagePackets
=
0
;
imagePacketsArrived
=
0
;
emit
imageReady
(
this
);
//qDebug() << "imageReady emitted. all packets arrived";
}
...
...
src/ui/MainWindow.cc
View file @
4b861414
...
...
@@ -788,6 +788,10 @@ void MainWindow::loadDockWidget(const QString& name)
{
createDockWidget
(
centerStack
->
currentWidget
(),
new
ParameterInterface
(
this
),
tr
(
"Onboard Parameters"
),
"PARAMETER_INTERFACE_DOCKWIDGET"
,
currentView
,
Qt
::
RightDockWidgetArea
);
}
else
if
(
name
==
"FILE_VIEW_DOCKWIDGET"
)
{
createDockWidget
(
centerStack
->
currentWidget
(),
new
QGCUASFileViewMulti
(
this
),
tr
(
"Onboard Files"
),
"FILE_VIEW_DOCKWIDGET"
,
VIEW_ENGINEER
,
Qt
::
RightDockWidgetArea
);
}
else
if
(
name
==
"UAS_STATUS_DETAILS_DOCKWIDGET"
)
{
createDockWidget
(
centerStack
->
currentWidget
(),
new
UASInfoWidget
(
this
),
tr
(
"Status Details"
),
"UAS_STATUS_DETAILS_DOCKWIDGET"
,
currentView
,
Qt
::
RightDockWidgetArea
);
...
...
src/ui/QGCUASFileView.cc
View file @
4b861414
...
...
@@ -17,6 +17,7 @@ QGCUASFileView::QGCUASFileView(QWidget *parent, QGCUASFileManager *manager) :
connect
(
ui
->
downloadButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
downloadFiles
()));
connect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
ui
->
messageArea
,
SLOT
(
appendPlainText
(
QString
)));
connect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
ui
->
messageArea
,
SLOT
(
appendPlainText
(
QString
)));
connect
(
_manager
,
SIGNAL
(
resetStatusMessages
()),
ui
->
messageArea
,
SLOT
(
clear
()));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment