File: udpserver.h

package info (click to toggle)
wfview 2.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,256 kB
  • sloc: cpp: 43,386; ansic: 3,196; sh: 32; xml: 29; makefile: 11
file content (263 lines) | stat: -rw-r--r-- 5,538 bytes parent folder | download
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QObject>
#include <QUdpSocket>
#include <QNetworkDatagram>
#include <QNetworkInterface>
#include <QHostInfo>
#include <QTimer>
#include <QMutex>
#include <QDateTime>
#include <QByteArray>
#include <QList>
#include <QVector>
#include <QMap>

// Allow easy endian-ness conversions
#include <QtEndian>

#include <QDebug>

#include "packettypes.h"
#include "rigidentities.h"
#include "udphandler.h"
#include "audiohandler.h"
#include "rigcommander.h"

extern void passcode(QString in,QByteArray& out);
extern QByteArray parseNullTerminatedString(QByteArray c, int s);

struct SEQBUFENTRY {
	QTime	timeSent;
	uint16_t seqNum;
	QByteArray data;
	quint8 retransmitCount;
};


struct SERVERUSER {
	QString username;
	QString password;
	quint8 userType;
};


struct RIGCONFIG {
	QString serialPort;
	quint32 baudRate;
	quint8 civAddr;
	bool civIsRadioModel;
	bool hasWiFi = false;
	bool hasEthernet=false;
    pttType_t pttType=pttCIV;
	audioSetup rxAudioSetup;
	audioSetup txAudioSetup;
	QString modelName;
	QString rigName;
#pragma pack(push, 1)
	union {
		struct {
			quint8 unused[7];        // 0x22
			quint16 commoncap;      // 0x27
			quint8 unusedb;           // 0x29
			quint8 macaddress[6];     // 0x2a
        };
		quint8 guid[GUIDLEN];                  // 0x20
	};
#pragma pack(pop)
	bool rigAvailable=false;
    rigCapabilities* rigCaps = Q_NULLPTR;
	rigCommander* rig = Q_NULLPTR;
	QThread* rigThread = Q_NULLPTR;
	audioHandler* rxaudio = Q_NULLPTR;
	QThread* rxAudioThread = Q_NULLPTR;
	audioHandler* txaudio = Q_NULLPTR;
	QThread* txAudioThread = Q_NULLPTR;
	QTimer* rxAudioTimer = Q_NULLPTR;
	QTimer* connectTimer = Q_NULLPTR;
	quint8 waterfallFormat;
     quint64 queueInterval=1000;
};


struct SERVERCONFIG {
	bool enabled;
    bool disableUI;
	bool lan;
	quint16 controlPort;
	quint16 civPort;
	quint16 audioPort;
	int audioOutput;
	int audioInput;
	quint8 resampleQuality;
	quint32 baudRate;
	QList <SERVERUSER> users;
	QList <RIGCONFIG*> rigs;
};

enum prefServerItem {
    s_enabled = 1 << 0,
    s_disableui = 1 << 1,
    s_lan = 1 << 2,
    s_controlPort = 1 << 3,
    s_civPort = 1 << 4,
    s_audioPort = 1 << 5,
    s_audioOutput = 1 << 6,
    s_audioInput = 1 << 7,
    s_resampleQuality = 1 << 8,
    s_baudRate = 1 << 9,
    s_users = 1 << 10,
    s_rigs = 1 << 11,
    s_all = 1 << 12
};


class udpServer : public QObject
{
	Q_OBJECT

public:
	explicit udpServer(SERVERCONFIG* config, QObject* parent = nullptr);
	~udpServer();

public slots:
	void init();
	void dataForServer(QByteArray);
	void receiveAudioData(const audioPacket &data);
    void receiveRigCaps(rigCapabilities* caps);

signals:
	void haveDataFromServer(QByteArray);
	void haveAudioData(audioPacket data);
	void haveNetworkStatus(networkStatus);

	void setupTxAudio(audioSetup);
	void setupRxAudio(audioSetup);



private:

	struct CLIENT {
		bool connected = false;
		QString type;
		QHostAddress ipAddress;
		quint16 port;
		QByteArray clientName;
		QDateTime	timeConnected;
		QDateTime lastHeard;
		bool isStreaming;
		quint16 civPort;
		quint16 audioPort;
		quint16 txBufferLen;
		quint32 myId;
		quint32 remoteId;
		quint16 txSeq=0;
		quint16 rxSeq;
		quint16 connSeq;
		quint16 pingSeq;
		quint32 rxPingTime; // 32bit as has other info
		quint16 authInnerSeq;
		quint16 authSeq;
		quint16 innerSeq;
		quint16 sendAudioSeq;
		quint8 macaddress[6];
		quint16 tokenRx;
		quint32 tokenTx;
		quint32 commonCap;
		quint8 wdseq;
		QUdpSocket* socket;


		QTimer* pingTimer;
		QTimer* idleTimer;
		QTimer* retransmitTimer;

		// Only used for audio.
		quint8 rxCodec;
		quint8 txCodec;
		quint16 rxSampleRate;
		quint16 txSampleRate;
		SERVERUSER user;


		QMap<quint16, QTime> rxSeqBuf;
		QMap<quint16, SEQBUFENTRY> txSeqBuf;
		QMap<quint16, int> rxMissing;

		QMutex txMutex;
		QMutex rxMutex;
		QMutex missMutex;

		quint16 seqPrefix;

		quint8 civId;
		bool isAuthenticated;
		CLIENT* controlClient = Q_NULLPTR;
		CLIENT* civClient = Q_NULLPTR;
		CLIENT* audioClient = Q_NULLPTR;
		quint8 guid[GUIDLEN];

        qint64 startTime;
        QTime clientTime;
        qint64 timeOffset;
        qint64 timeDifference = 0;
	};

	void controlReceived();
	void civReceived();
	void audioReceived();
	void commonReceived(QList<CLIENT*>* l,CLIENT* c, QByteArray r);

	void sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply);
	void sendControl(CLIENT* c, quint8 type, quint16 seq);
	void sendLoginResponse(CLIENT* c, bool allowed);
	void sendCapabilities(CLIENT* c);
	void sendConnectionInfo(CLIENT* c,quint8 guid[GUIDLEN]);
	void sendTokenResponse(CLIENT* c,quint8 type);
	void sendStatus(CLIENT* c);
	void sendRetransmitRequest(CLIENT* c);
	void watchdog();
	void deleteConnection(QList<CLIENT*> *l, CLIENT* c);

	SERVERCONFIG *config;

	QUdpSocket* udpControl = Q_NULLPTR;
	QUdpSocket* udpCiv = Q_NULLPTR;
	QUdpSocket* udpAudio = Q_NULLPTR;
	QHostAddress localIP;
	quint8 macAddress[6];
	
	quint32 controlId = 0;
	quint32 civId = 0;
	quint32 audioId = 0;

	QMutex udpMutex; // Used for critical operations.
	QMutex connMutex;
	QMutex audioMutex;

	QList <CLIENT*> controlClients = QList<CLIENT*>();
	QList <CLIENT*> civClients = QList<CLIENT*>();
	QList <CLIENT*> audioClients = QList<CLIENT*>();

    //QTime timeStarted;


	audioSetup outAudio;
	audioSetup inAudio;

	quint16 rxSampleRate = 0;
	quint16 txSampleRate = 0;
	quint8 rxCodec = 0;
	quint8 txCodec = 0;

	QHostAddress hasTxAudio;
	QTimer* wdTimer;

	networkStatus status;
    cachingQueue* queue;
};


#endif // UDPSERVER_H