MockMavlinkFileServer.h 5.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*=====================================================================
 
 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"
Don Gagne's avatar
Don Gagne committed
28 29
#include "QGCUASFileManager.h"

30 31 32 33 34
/// @file
///     @brief Mock implementation of Mavlink FTP server. Used as mavlink plugin to MockUAS.
///             Only root directory access is supported.
///
///     @author Don Gagne <don@thegagnes.com>
Don Gagne's avatar
Don Gagne committed
35 36

#include <QStringList>
37 38 39 40 41 42

class MockMavlinkFileServer : public MockMavlinkInterface
{
    Q_OBJECT
    
public:
43 44 45 46
    /// @brief Constructor for MockMavlinkFileServer
    ///     @param System ID for QGroundControl App
    ///     @pqram System ID for this Server
    MockMavlinkFileServer(uint8_t systemIdQGC, uint8_t systemIdServer);
47
    
48 49
    /// @brief Sets the list of files returned by the List command. Prepend names with F or D
    /// to indicate (F)ile or (D)irectory.
Don Gagne's avatar
Don Gagne committed
50
    void setFileList(QStringList& fileList) { _fileList = fileList; }
51
    
52 53 54 55 56 57 58
    /// @brief By calling setErrorMode with one of these modes you can cause the server to simulate an error.
    typedef enum {
        errModeNone,                ///< No error, respond correctly
        errModeNoResponse,          ///< No response to any request, client should eventually time out with no Ack
        errModeNakResponse,         ///< Nak all requests
        errModeNoSecondResponse,    ///< No response to subsequent request to initial command
        errModeNakSecondResponse,   ///< Nak subsequent request to initial command
59
        errModeBadSequence          ///< Return response with bad sequence number
60 61 62 63 64 65 66 67 68 69 70 71 72
    } ErrorMode_t;
    
    /// @brief Sets the error mode for command responses. This allows you to simulate various server errors.
    void setErrorMode(ErrorMode_t errMode) { _errMode = errMode; };
    
    /// @brief Array of failure modes you can cycle through for testing. By looping through this array you can avoid
    /// hardcoding the specific error modes in your unit test. This way when new error modes are added your unit test
    /// code may not need to be modified.
    static const ErrorMode_t rgFailureModes[];
    
    /// @brief The number of ErrorModes in the rgFailureModes array.
    static const size_t cFailureModes;
    
Don Gagne's avatar
Don Gagne committed
73 74
    // From MockMavlinkInterface
    virtual void sendMessage(mavlink_message_t message);
75
    
76
    /// @brief Used to represent a single test case for download testing.
77
    struct FileTestCase {
78 79 80
        const char* filename;               ///< Filename to download
        uint8_t     length;                 ///< Length of file in bytes
        bool        fMultiPacketResponse;   ///< true: multiple acks required to download, false: single ack contains entire download
81 82
    };
    
83
    /// @brief The numbers of test cases in the rgFileTestCases array.
84
    static const size_t cFileTestCases = 3;
85 86
    
    /// @brief The set of files supported by the mock server for testing purposes. Each one represents a different edge case for testing.
87 88 89
    static const FileTestCase rgFileTestCases[cFileTestCases];
    
signals:
90
    /// @brief You can connect to this signal to be notified when the server receives a Terminate command.
91
    void terminateCommandReceived(void);
92
    
Don Gagne's avatar
Don Gagne committed
93
private:
94 95 96 97 98 99 100 101
    void _sendAck(uint16_t seqNumber);
    void _sendNak(QGCUASFileManager::ErrorCode error, uint16_t seqNumber);
    void _emitResponse(QGCUASFileManager::Request* request, uint16_t seqNumber);
    void _listCommand(QGCUASFileManager::Request* request, uint16_t seqNumber);
    void _openCommand(QGCUASFileManager::Request* request, uint16_t seqNumber);
    void _readCommand(QGCUASFileManager::Request* request, uint16_t seqNumber);
    void _terminateCommand(QGCUASFileManager::Request* request, uint16_t seqNumber);
    uint16_t _nextSeqNumber(uint16_t seqNumber);
102 103
    
    QStringList _fileList;  ///< List of files returned by List command
104
    
105
    static const uint8_t    _sessionId;
106 107
    uint8_t                 _readFileLength;    ///< Length of active file being read
    ErrorMode_t             _errMode;           ///< Currently set error mode, as specified by setErrorMode
108 109
    const uint8_t           _systemIdServer;    ///< System ID for server
    const uint8_t           _systemIdQGC;       ///< QGC System ID
110 111 112
};

#endif