2021-02-16 16:16:46 +00:00
|
|
|
#ifndef UDPSERVER_H
|
|
|
|
#define UDPSERVER_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QUdpSocket>
|
|
|
|
#include <QNetworkDatagram>
|
2021-02-28 20:10:07 +00:00
|
|
|
#include <QNetworkInterface>
|
2021-02-16 16:16:46 +00:00
|
|
|
#include <QHostInfo>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QMutex>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QByteArray>
|
|
|
|
#include <QList>
|
2021-02-28 20:10:07 +00:00
|
|
|
#include <QVector>
|
2021-06-01 22:32:39 +00:00
|
|
|
#include <QMap>
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
// Allow easy endian-ness conversions
|
|
|
|
#include <QtEndian>
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
2021-02-21 21:05:58 +00:00
|
|
|
#include "packettypes.h"
|
2021-02-28 20:10:07 +00:00
|
|
|
#include "rigidentities.h"
|
2022-01-22 15:12:36 +00:00
|
|
|
#include "udphandler.h"
|
2021-02-28 20:10:07 +00:00
|
|
|
#include "audiohandler.h"
|
2022-01-26 09:49:52 +00:00
|
|
|
#include "rigcommander.h"
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
extern void passcode(QString in,QByteArray& out);
|
|
|
|
extern QByteArray parseNullTerminatedString(QByteArray c, int s);
|
|
|
|
|
2021-02-28 20:10:07 +00:00
|
|
|
struct SEQBUFENTRY {
|
|
|
|
QTime timeSent;
|
|
|
|
uint16_t seqNum;
|
|
|
|
QByteArray data;
|
|
|
|
quint8 retransmitCount;
|
|
|
|
};
|
|
|
|
|
2022-01-04 18:34:34 +00:00
|
|
|
|
|
|
|
struct SERVERUSER {
|
|
|
|
QString username;
|
|
|
|
QString password;
|
|
|
|
quint8 userType;
|
|
|
|
};
|
|
|
|
|
2022-04-20 12:35:23 +00:00
|
|
|
|
2022-01-26 09:49:52 +00:00
|
|
|
struct RIGCONFIG {
|
|
|
|
QString serialPort;
|
|
|
|
quint32 baudRate;
|
|
|
|
unsigned char civAddr;
|
|
|
|
bool civIsRadioModel;
|
|
|
|
bool forceRTSasPTT;
|
|
|
|
bool hasWiFi = false;
|
|
|
|
bool hasEthernet=false;
|
|
|
|
audioSetup rxAudioSetup;
|
|
|
|
audioSetup txAudioSetup;
|
|
|
|
QString modelName;
|
|
|
|
QString rigName;
|
2022-04-20 12:35:23 +00:00
|
|
|
#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)
|
2022-01-26 09:49:52 +00:00
|
|
|
bool rigAvailable=false;
|
|
|
|
rigCapabilities rigCaps;
|
|
|
|
rigCommander* rig = Q_NULLPTR;
|
|
|
|
QThread* rigThread = Q_NULLPTR;
|
2022-05-14 12:45:56 +00:00
|
|
|
audioHandler* rxaudio = Q_NULLPTR;
|
2022-01-26 09:49:52 +00:00
|
|
|
QThread* rxAudioThread = Q_NULLPTR;
|
2022-05-14 12:45:56 +00:00
|
|
|
audioHandler* txaudio = Q_NULLPTR;
|
2022-01-26 09:49:52 +00:00
|
|
|
QThread* txAudioThread = Q_NULLPTR;
|
|
|
|
QTimer* rxAudioTimer = Q_NULLPTR;
|
2022-01-29 22:50:58 +00:00
|
|
|
QTimer* connectTimer = Q_NULLPTR;
|
2022-05-13 17:45:13 +00:00
|
|
|
quint8 waterfallFormat;
|
2022-01-26 09:49:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-01-04 18:34:34 +00:00
|
|
|
struct SERVERCONFIG {
|
|
|
|
bool enabled;
|
|
|
|
bool lan;
|
|
|
|
quint16 controlPort;
|
|
|
|
quint16 civPort;
|
|
|
|
quint16 audioPort;
|
|
|
|
int audioOutput;
|
|
|
|
int audioInput;
|
|
|
|
quint8 resampleQuality;
|
|
|
|
quint32 baudRate;
|
|
|
|
QList <SERVERUSER> users;
|
2022-01-27 19:11:16 +00:00
|
|
|
QList <RIGCONFIG*> rigs;
|
2022-01-04 18:34:34 +00:00
|
|
|
};
|
|
|
|
|
2023-06-08 20:58:22 +00:00
|
|
|
enum prefServerItem {
|
2023-02-22 06:54:15 +00:00
|
|
|
s_enabled = 1 << 0,
|
|
|
|
s_lan = 1 << 1,
|
|
|
|
s_controlPort = 1 << 2,
|
|
|
|
s_civPort = 1 << 3,
|
|
|
|
s_audioPort = 1 << 4,
|
|
|
|
s_audioOutput = 1 << 5,
|
|
|
|
s_audioInput = 1 << 6,
|
|
|
|
s_resampleQuality = 1 << 7,
|
|
|
|
s_baudRate = 1 << 8,
|
|
|
|
s_users = 1 << 9,
|
|
|
|
s_rigs = 1 << 10,
|
|
|
|
s_all = 1 << 11
|
|
|
|
};
|
|
|
|
|
2022-01-04 18:34:34 +00:00
|
|
|
|
2021-02-16 16:16:46 +00:00
|
|
|
class udpServer : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2022-05-08 18:31:05 +00:00
|
|
|
explicit udpServer(SERVERCONFIG* config, QObject* parent = nullptr);
|
2021-02-16 16:16:46 +00:00
|
|
|
~udpServer();
|
|
|
|
|
|
|
|
public slots:
|
2022-01-16 18:47:13 +00:00
|
|
|
void init();
|
2021-02-18 09:14:41 +00:00
|
|
|
void dataForServer(QByteArray);
|
2021-03-01 19:53:12 +00:00
|
|
|
void receiveAudioData(const audioPacket &data);
|
2021-02-28 20:10:07 +00:00
|
|
|
void receiveRigCaps(rigCapabilities caps);
|
2021-02-18 09:14:41 +00:00
|
|
|
|
|
|
|
signals:
|
|
|
|
void haveDataFromServer(QByteArray);
|
2021-03-22 09:10:03 +00:00
|
|
|
void haveAudioData(audioPacket data);
|
2022-01-22 15:12:36 +00:00
|
|
|
void haveNetworkStatus(networkStatus);
|
2021-05-22 20:09:04 +00:00
|
|
|
|
2021-06-04 07:24:26 +00:00
|
|
|
void setupTxAudio(audioSetup);
|
|
|
|
void setupRxAudio(audioSetup);
|
2021-05-22 20:09:04 +00:00
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
struct CLIENT {
|
|
|
|
bool connected = false;
|
2021-05-14 08:55:02 +00:00
|
|
|
QString type;
|
2021-02-16 16:16:46 +00:00
|
|
|
QHostAddress ipAddress;
|
|
|
|
quint16 port;
|
|
|
|
QByteArray clientName;
|
2021-02-17 23:10:26 +00:00
|
|
|
QDateTime timeConnected;
|
|
|
|
QDateTime lastHeard;
|
|
|
|
bool isStreaming;
|
|
|
|
quint16 civPort;
|
|
|
|
quint16 audioPort;
|
|
|
|
quint16 txBufferLen;
|
2021-02-16 16:16:46 +00:00
|
|
|
quint32 myId;
|
|
|
|
quint32 remoteId;
|
2021-02-28 20:10:07 +00:00
|
|
|
quint16 txSeq=0;
|
|
|
|
quint16 rxSeq;
|
|
|
|
quint16 connSeq;
|
2021-02-16 16:16:46 +00:00
|
|
|
quint16 pingSeq;
|
2021-02-23 20:49:26 +00:00
|
|
|
quint32 rxPingTime; // 32bit as has other info
|
2022-04-20 12:35:23 +00:00
|
|
|
quint16 authInnerSeq;
|
2021-02-16 16:16:46 +00:00
|
|
|
quint16 authSeq;
|
|
|
|
quint16 innerSeq;
|
2021-02-28 20:10:07 +00:00
|
|
|
quint16 sendAudioSeq;
|
2022-04-20 12:35:23 +00:00
|
|
|
quint8 macaddress[6];
|
2021-02-16 16:16:46 +00:00
|
|
|
quint16 tokenRx;
|
2021-02-16 20:55:30 +00:00
|
|
|
quint32 tokenTx;
|
2021-02-23 20:49:26 +00:00
|
|
|
quint32 commonCap;
|
2021-02-17 23:10:26 +00:00
|
|
|
quint8 wdseq;
|
2021-02-16 16:16:46 +00:00
|
|
|
QUdpSocket* socket;
|
|
|
|
|
2021-02-17 23:10:26 +00:00
|
|
|
|
2021-02-16 16:16:46 +00:00
|
|
|
QTimer* pingTimer;
|
|
|
|
QTimer* idleTimer;
|
2021-02-28 20:10:07 +00:00
|
|
|
QTimer* retransmitTimer;
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
// Only used for audio.
|
|
|
|
quint8 rxCodec;
|
|
|
|
quint8 txCodec;
|
|
|
|
quint16 rxSampleRate;
|
|
|
|
quint16 txSampleRate;
|
2021-02-23 20:49:26 +00:00
|
|
|
SERVERUSER user;
|
2021-02-28 20:10:07 +00:00
|
|
|
|
2021-06-01 22:32:39 +00:00
|
|
|
|
|
|
|
QMap<quint16, QTime> rxSeqBuf;
|
|
|
|
QMap<quint16, SEQBUFENTRY> txSeqBuf;
|
|
|
|
QMap<quint16, int> rxMissing;
|
|
|
|
|
2021-05-14 08:55:02 +00:00
|
|
|
QMutex txMutex;
|
|
|
|
QMutex rxMutex;
|
|
|
|
QMutex missMutex;
|
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
quint16 seqPrefix;
|
2021-05-14 08:55:02 +00:00
|
|
|
|
|
|
|
quint8 civId;
|
2021-06-10 09:57:39 +00:00
|
|
|
bool isAuthenticated;
|
2021-06-11 08:56:19 +00:00
|
|
|
CLIENT* controlClient = Q_NULLPTR;
|
2021-06-11 09:08:04 +00:00
|
|
|
CLIENT* civClient = Q_NULLPTR;
|
|
|
|
CLIENT* audioClient = Q_NULLPTR;
|
2022-01-29 22:50:58 +00:00
|
|
|
quint8 guid[GUIDLEN];
|
2021-02-16 16:16:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void controlReceived();
|
|
|
|
void civReceived();
|
|
|
|
void audioReceived();
|
2021-02-28 20:10:07 +00:00
|
|
|
void commonReceived(QList<CLIENT*>* l,CLIENT* c, QByteArray r);
|
|
|
|
|
2021-02-18 13:49:19 +00:00
|
|
|
void sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply);
|
2021-02-23 20:49:26 +00:00
|
|
|
void sendControl(CLIENT* c, quint8 type, quint16 seq);
|
2021-02-28 20:10:07 +00:00
|
|
|
void sendLoginResponse(CLIENT* c, bool allowed);
|
2021-02-16 16:16:46 +00:00
|
|
|
void sendCapabilities(CLIENT* c);
|
2022-01-29 22:50:58 +00:00
|
|
|
void sendConnectionInfo(CLIENT* c,quint8 guid[GUIDLEN]);
|
2021-02-17 23:10:26 +00:00
|
|
|
void sendTokenResponse(CLIENT* c,quint8 type);
|
|
|
|
void sendStatus(CLIENT* c);
|
2021-02-28 20:10:07 +00:00
|
|
|
void sendRetransmitRequest(CLIENT* c);
|
2021-06-11 11:53:00 +00:00
|
|
|
void watchdog();
|
2021-02-18 13:49:19 +00:00
|
|
|
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
|
|
|
|
|
2022-04-20 12:35:23 +00:00
|
|
|
SERVERCONFIG *config;
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
QUdpSocket* udpControl = Q_NULLPTR;
|
|
|
|
QUdpSocket* udpCiv = Q_NULLPTR;
|
|
|
|
QUdpSocket* udpAudio = Q_NULLPTR;
|
|
|
|
QHostAddress localIP;
|
2022-04-20 12:35:23 +00:00
|
|
|
quint8 macAddress[6];
|
2021-02-16 16:16:46 +00:00
|
|
|
|
|
|
|
quint32 controlId = 0;
|
|
|
|
quint32 civId = 0;
|
|
|
|
quint32 audioId = 0;
|
|
|
|
|
2021-05-14 08:55:02 +00:00
|
|
|
QMutex udpMutex; // Used for critical operations.
|
|
|
|
QMutex connMutex;
|
2021-11-15 19:28:44 +00:00
|
|
|
QMutex audioMutex;
|
2021-02-18 13:49:19 +00:00
|
|
|
|
2021-02-16 16:16:46 +00:00
|
|
|
QList <CLIENT*> controlClients = QList<CLIENT*>();
|
|
|
|
QList <CLIENT*> civClients = QList<CLIENT*>();
|
|
|
|
QList <CLIENT*> audioClients = QList<CLIENT*>();
|
2021-03-22 09:10:03 +00:00
|
|
|
|
2022-05-05 17:09:16 +00:00
|
|
|
//QTime timeStarted;
|
2021-03-22 09:10:03 +00:00
|
|
|
|
|
|
|
|
2021-06-04 13:25:07 +00:00
|
|
|
audioSetup outAudio;
|
2021-06-04 13:38:59 +00:00
|
|
|
audioSetup inAudio;
|
2021-06-04 13:25:07 +00:00
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
quint16 rxSampleRate = 0;
|
|
|
|
quint16 txSampleRate = 0;
|
|
|
|
quint8 rxCodec = 0;
|
|
|
|
quint8 txCodec = 0;
|
|
|
|
|
|
|
|
QHostAddress hasTxAudio;
|
2021-06-11 11:53:00 +00:00
|
|
|
QTimer* wdTimer;
|
2022-02-02 16:02:40 +00:00
|
|
|
|
|
|
|
networkStatus status;
|
2021-02-16 16:16:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-05-05 17:09:16 +00:00
|
|
|
#endif // UDPSERVER_H
|