TCPLink.h 5.17 KB
Newer Older
Don Gagne's avatar
Don Gagne committed
1
2
3
4
/*=====================================================================
 
 QGroundControl Open Source Ground Control Station
 
5
 (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
Don Gagne's avatar
Don Gagne committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
 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/>.
 
 ======================================================================*/

24
25
26
27
/// @file
///     @brief TCP link type for SITL support
///
///     @author Don Gagne <don@thegagnes.com>
Don Gagne's avatar
Don Gagne committed
28
29
30
31
32
33
34
35
36
37

#ifndef TCPLINK_H
#define TCPLINK_H

#include <QString>
#include <QList>
#include <QMap>
#include <QMutex>
#include <QHostAddress>
#include <LinkInterface.h>
38
#include "QGCConfig.h"
39
#include "LinkManager.h"
Don Gagne's avatar
Don Gagne committed
40

41
42
43
44
45
46
// Even though QAbstractSocket::SocketError is used in a signal by Qt, Qt doesn't declare it as a meta type.
// This in turn causes debug output to be kicked out about not being able to queue the signal. We declare it
// as a meta type to silence that.
#include <QMetaType>
#include <QTcpSocket>

Don Gagne's avatar
Don Gagne committed
47
48
//#define TCPLINK_READWRITE_DEBUG   // Use to debug data reads/writes

49
50
class TCPLinkUnitTest;

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#define QGC_TCP_PORT 5760

class TCPConfiguration : public LinkConfiguration
{
public:

    /*!
     * @brief Regular constructor
     *
     * @param[in] name Configuration (user friendly) name
     */
    TCPConfiguration(const QString& name);

    /*!
     * @brief Copy contructor
     *
     * When manipulating data, you create a copy of the configuration, edit it
     * and then transfer its content to the original (using copyFrom() below). Use this
     * contructor to create an editable copy.
     *
     * @param[in] source Original configuration
     */
    TCPConfiguration(TCPConfiguration* source);

    /*!
     * @brief The TCP port
     *
     * @return Port number
     */
    quint16 port   () { return _port; }

    /*!
     * @brief Set the TCP port
     *
     * @param[in] port Port number
     */
    void setPort   (quint16 port);

    /*!
     * @brief The host address
     *
     * @return Host address
     */
    const QHostAddress& address   () { return _address; }

    /*!
     * @brief Set the host address
     *
     * @param[in] address Host address
     */
    void setAddress (const QHostAddress& address);

    /// From LinkConfiguration
    int  type() { return LinkConfiguration::TypeTcp; }
    void copyFrom(LinkConfiguration* source);
    void loadSettings(QSettings& settings, const QString& root);
    void saveSettings(QSettings& settings, const QString& root);
    void updateSettings();

private:
    QHostAddress _address;
    quint16 _port;
};

Don Gagne's avatar
Don Gagne committed
115
116
117
class TCPLink : public LinkInterface
{
    Q_OBJECT
118
    
119
    friend class TCPLinkUnitTest;
120
    friend class TCPConfiguration;
121
    friend class LinkManager;
Don Gagne's avatar
Don Gagne committed
122
    
123
public:
124
    QTcpSocket* getSocket(void) { return _socket; }
Don Gagne's avatar
Don Gagne committed
125
    
126
127
    void signalBytesWritten(void);

128
129
130
131
132
    // LinkInterface methods
    virtual int     getId(void) const;
    virtual QString getName(void) const;
    virtual bool    isConnected(void) const;
    virtual void    requestReset(void) {};
133
134
135
136
137

    // Extensive statistics for scientific purposes
    qint64 getConnectionSpeed() const;
    qint64 getCurrentInDataRate() const;
    qint64 getCurrentOutDataRate() const;
Don Gagne's avatar
Don Gagne committed
138
    
139
140
141
142
143
    // These are left unimplemented in order to cause linker errors which indicate incorrect usage of
    // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
    bool connect(void);
    bool disconnect(void);
    
Don Gagne's avatar
Don Gagne committed
144
145
public slots:
    
146
    // From LinkInterface
147
    void writeBytes(const char* data, qint64 length);
148
149
    void waitForBytesWritten(int msecs);
    void waitForReadyRead(int msecs);
150
151
152
153
154
155
156

protected slots:
    void _socketError(QAbstractSocket::SocketError socketError);

    // From LinkInterface
    virtual void readBytes(void);

Don Gagne's avatar
Don Gagne committed
157
protected:
158
159
    // From LinkInterface->QThread
    virtual void run(void);
160
    
Don Gagne's avatar
Don Gagne committed
161
private:
162
163
164
165
    // Links are only created/destroyed by LinkManager so constructor/destructor is not public
    TCPLink(TCPConfiguration* config);
    ~TCPLink();
    
166
    // From LinkInterface
167
168
    virtual bool _connect(void);
    virtual bool _disconnect(void);
169
170
171

    bool _hardwareConnect();
    void _restartConnection();
172

Don Gagne's avatar
Don Gagne committed
173
#ifdef TCPLINK_READWRITE_DEBUG
174
    void _writeDebugBytes(const char *data, qint16 size);
Don Gagne's avatar
Don Gagne committed
175
#endif
176

177
178
179
180
    int               _linkId;
    TCPConfiguration* _config;
    QTcpSocket*       _socket;
    bool              _socketIsConnected;
Don Gagne's avatar
Don Gagne committed
181
    
182
183
184
185
186
187
188
189
    quint64 _bitsSentTotal;
    quint64 _bitsSentCurrent;
    quint64 _bitsSentMax;
    quint64 _bitsReceivedTotal;
    quint64 _bitsReceivedCurrent;
    quint64 _bitsReceivedMax;
    quint64 _connectionStartTime;
    QMutex  _statisticsMutex;
Don Gagne's avatar
Don Gagne committed
190
191
192
};

#endif // TCPLINK_H