Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mavlink FTP implementation List command #725

Merged
merged 10 commits into from
Jun 26, 2014
Merged
9 changes: 7 additions & 2 deletions qgroundcontrol.pro
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

#
Expand Down
148 changes: 148 additions & 0 deletions src/qgcunittest/MockMavlinkFileServer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*=====================================================================
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);
}
52 changes: 52 additions & 0 deletions src/qgcunittest/MockMavlinkFileServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*=====================================================================
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
9 changes: 9 additions & 0 deletions src/qgcunittest/MockMavlinkInterface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// MockMavlinkInterface.cc
// QGroundControl
//
// Created by Donald Gagne on 6/19/14.
// Copyright (c) 2014 Donald Gagne. All rights reserved.
//

#include "MockMavlinkInterface.h"
44 changes: 44 additions & 0 deletions src/qgcunittest/MockMavlinkInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*=====================================================================
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
14 changes: 13 additions & 1 deletion src/qgcunittest/MockUAS.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ QString MockUAS::_bogusStaticString;

MockUAS::MockUAS(void) :
_systemType(MAV_TYPE_QUADROTOR),
_systemId(1)
_systemId(1),
_mavlinkPlugin(NULL)
{

}
Expand All @@ -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);
}
15 changes: 11 additions & 4 deletions src/qgcunittest/MockUAS.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "UASInterface.h"
#include "MockQGCUASParamManager.h"
#include "MockMavlinkInterface.h"

#include <limits>

Expand All @@ -50,6 +51,9 @@ class MockUAS : public UASInterface
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);
Expand All @@ -63,12 +67,15 @@ class MockUAS : public UASInterface
/// 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; };
Expand Down Expand Up @@ -112,9 +119,7 @@ class MockUAS : public UASInterface
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; };
Expand Down Expand Up @@ -182,6 +187,8 @@ public slots:
int _systemId;

MockQGCUASParamManager _paramManager;

MockMavlinkInterface* _mavlinkPlugin; ///< Mock Mavlink plugin, NULL for none

// Bogus variables used for return types of NYI methods
QString _bogusString;
Expand Down
Loading