2021-02-03 20:00:40 +00:00
|
|
|
#ifndef UDPHANDLER_H
|
|
|
|
#define UDPHANDLER_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QUdpSocket>
|
|
|
|
#include <QNetworkDatagram>
|
|
|
|
#include <QHostInfo>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QMutex>
|
2021-02-06 10:54:20 +00:00
|
|
|
#include <QDateTime>
|
2021-02-11 19:18:35 +00:00
|
|
|
#include <QByteArray>
|
2021-02-22 22:25:09 +00:00
|
|
|
#include <QVector>
|
2021-05-17 15:03:53 +00:00
|
|
|
#include <QMap>
|
2022-01-23 17:54:40 +00:00
|
|
|
#include <QUuid>
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
// Allow easy endian-ness conversions
|
|
|
|
#include <QtEndian>
|
|
|
|
|
|
|
|
// Needed for audio
|
|
|
|
#include <QBuffer>
|
2021-02-08 08:31:48 +00:00
|
|
|
#include <QThread>
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
2021-02-11 19:18:35 +00:00
|
|
|
#include "audiohandler.h"
|
2021-02-20 18:29:23 +00:00
|
|
|
#include "packettypes.h"
|
2021-02-08 08:31:48 +00:00
|
|
|
|
2021-02-14 07:53:55 +00:00
|
|
|
|
2021-03-01 19:53:12 +00:00
|
|
|
struct udpPreferences {
|
|
|
|
QString ipAddress;
|
|
|
|
quint16 controlLANPort;
|
|
|
|
quint16 serialLANPort;
|
|
|
|
quint16 audioLANPort;
|
|
|
|
QString username;
|
|
|
|
QString password;
|
2021-03-27 16:07:17 +00:00
|
|
|
QString clientName;
|
2022-04-18 19:29:50 +00:00
|
|
|
quint8 waterfallFormat;
|
2021-03-01 19:53:12 +00:00
|
|
|
};
|
2021-02-13 23:25:24 +00:00
|
|
|
|
2022-01-22 15:12:36 +00:00
|
|
|
struct networkStatus {
|
|
|
|
quint8 rxAudioBufferPercent;
|
|
|
|
quint8 txAudioBufferPercent;
|
|
|
|
quint8 rxAudioLevel;
|
|
|
|
quint8 txAudioLevel;
|
|
|
|
quint16 rxLatency;
|
|
|
|
quint16 txLatency;
|
2022-04-06 20:52:22 +00:00
|
|
|
bool rxUnderrun;
|
|
|
|
bool txUnderrun;
|
|
|
|
quint16 rxCurrentLatency;
|
|
|
|
quint16 txCurrentLatency;
|
2022-01-29 22:50:58 +00:00
|
|
|
quint32 packetsSent=0;
|
|
|
|
quint32 packetsLost=0;
|
|
|
|
quint16 rtt=0;
|
|
|
|
quint32 networkLatency=0;
|
2022-01-22 15:12:36 +00:00
|
|
|
QString message;
|
|
|
|
};
|
|
|
|
|
2021-02-15 19:28:17 +00:00
|
|
|
void passcode(QString in, QByteArray& out);
|
2021-02-13 23:25:24 +00:00
|
|
|
QByteArray parseNullTerminatedString(QByteArray c, int s);
|
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
// Parent class that contains all common items.
|
|
|
|
class udpBase : public QObject
|
|
|
|
{
|
|
|
|
|
2021-02-27 00:37:00 +00:00
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
public:
|
2021-02-04 20:09:09 +00:00
|
|
|
~udpBase();
|
|
|
|
|
2022-01-23 15:06:31 +00:00
|
|
|
void init(quint16 local);
|
|
|
|
|
|
|
|
void reconnect();
|
2021-02-04 20:20:23 +00:00
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
void dataReceived(QByteArray r);
|
2021-02-22 22:25:09 +00:00
|
|
|
void sendPing();
|
2021-02-24 11:00:23 +00:00
|
|
|
void sendRetransmitRange(quint16 first, quint16 second, quint16 third,quint16 fourth);
|
2021-02-22 22:25:09 +00:00
|
|
|
|
2021-02-18 15:54:26 +00:00
|
|
|
void sendControl(bool tracked,quint8 id, quint16 seq);
|
2021-02-03 20:00:40 +00:00
|
|
|
|
2022-04-18 19:29:50 +00:00
|
|
|
void printHex(const QByteArray& pdata);
|
|
|
|
void printHex(const QByteArray& pdata, bool printVert, bool printHoriz);
|
|
|
|
|
|
|
|
|
2021-02-20 18:29:23 +00:00
|
|
|
QTime timeStarted;
|
|
|
|
|
2021-02-07 12:59:41 +00:00
|
|
|
QUdpSocket* udp=Q_NULLPTR;
|
2021-02-13 23:25:24 +00:00
|
|
|
uint32_t myId = 0;
|
|
|
|
uint32_t remoteId = 0;
|
2021-03-06 14:33:31 +00:00
|
|
|
uint8_t authSeq = 0x00;
|
2021-02-03 20:00:40 +00:00
|
|
|
uint16_t sendSeqB = 0;
|
|
|
|
uint16_t sendSeq = 1;
|
2021-02-22 22:25:09 +00:00
|
|
|
uint16_t lastReceivedSeq = 1;
|
2021-02-03 20:00:40 +00:00
|
|
|
uint16_t pkt0SendSeq = 0;
|
|
|
|
uint16_t periodicSeq = 0;
|
2021-02-06 10:54:20 +00:00
|
|
|
quint64 latency = 0;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
QString username = "";
|
|
|
|
QString password = "";
|
|
|
|
QHostAddress radioIP;
|
|
|
|
QHostAddress localIP;
|
|
|
|
bool isAuthenticated = false;
|
2021-02-08 16:53:26 +00:00
|
|
|
quint16 localPort=0;
|
|
|
|
quint16 port=0;
|
2021-02-03 20:00:40 +00:00
|
|
|
bool periodicRunning = false;
|
|
|
|
bool sentPacketConnect2 = false;
|
2021-02-25 17:53:01 +00:00
|
|
|
QTime lastReceived =QTime::currentTime();
|
2021-03-03 09:50:15 +00:00
|
|
|
QMutex udpMutex;
|
|
|
|
QMutex txBufferMutex;
|
|
|
|
QMutex rxBufferMutex;
|
2021-05-17 15:03:53 +00:00
|
|
|
QMutex missingMutex;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
struct SEQBUFENTRY {
|
2021-02-24 22:56:40 +00:00
|
|
|
QTime timeSent;
|
2021-02-03 20:00:40 +00:00
|
|
|
uint16_t seqNum;
|
|
|
|
QByteArray data;
|
2021-02-23 20:48:53 +00:00
|
|
|
quint8 retransmitCount;
|
2021-02-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
2021-05-17 15:03:53 +00:00
|
|
|
QMap<quint16, QTime> rxSeqBuf;
|
|
|
|
QMap<quint16, SEQBUFENTRY> txSeqBuf;
|
|
|
|
QMap<quint16, int> rxMissing;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
void sendTrackedPacket(QByteArray d);
|
|
|
|
void purgeOldEntries();
|
|
|
|
|
2021-02-21 14:53:42 +00:00
|
|
|
QTimer* areYouThereTimer = Q_NULLPTR; // Send are-you-there packets every second until a response is received.
|
|
|
|
QTimer* pingTimer = Q_NULLPTR; // Start sending pings immediately.
|
|
|
|
QTimer* idleTimer = Q_NULLPTR; // Start watchdog once we are connected.
|
2021-02-13 23:25:24 +00:00
|
|
|
|
2021-02-25 17:53:01 +00:00
|
|
|
QTimer* watchdogTimer = Q_NULLPTR;
|
2021-02-27 00:37:00 +00:00
|
|
|
QTimer* retransmitTimer = Q_NULLPTR;
|
2021-02-25 17:53:01 +00:00
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
QDateTime lastPingSentTime;
|
|
|
|
uint16_t pingSendSeq = 0;
|
|
|
|
|
2021-02-14 07:53:55 +00:00
|
|
|
quint16 areYouThereCounter=0;
|
|
|
|
|
2021-02-14 10:40:47 +00:00
|
|
|
quint32 packetsSent=0;
|
|
|
|
quint32 packetsLost=0;
|
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
quint16 seqPrefix = 0;
|
2021-08-15 10:19:34 +00:00
|
|
|
QString connectionType="";
|
2021-05-17 15:03:53 +00:00
|
|
|
int congestion = 0;
|
|
|
|
|
|
|
|
|
2021-02-27 00:37:00 +00:00
|
|
|
private:
|
|
|
|
void sendRetransmitRequest();
|
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Class for all (pseudo) serial communications
|
2021-02-13 23:25:24 +00:00
|
|
|
class udpCivData : public udpBase
|
2021-02-03 20:00:40 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2022-04-18 19:29:50 +00:00
|
|
|
udpCivData(QHostAddress local, QHostAddress ip, quint16 civPort, bool splitWf, quint16 lport);
|
2021-02-13 23:25:24 +00:00
|
|
|
~udpCivData();
|
2021-02-03 20:00:40 +00:00
|
|
|
QMutex serialmutex;
|
|
|
|
|
|
|
|
signals:
|
2021-02-13 23:25:24 +00:00
|
|
|
int receive(QByteArray);
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
public slots:
|
2021-02-13 23:25:24 +00:00
|
|
|
void send(QByteArray d);
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
private:
|
2021-02-25 17:53:01 +00:00
|
|
|
void watchdog();
|
2021-02-13 23:25:24 +00:00
|
|
|
void dataReceived();
|
|
|
|
void sendOpenClose(bool close);
|
2021-02-25 17:53:01 +00:00
|
|
|
|
|
|
|
QTimer* startCivDataTimer = Q_NULLPTR;
|
2022-04-18 19:29:50 +00:00
|
|
|
bool splitWaterfall = false;
|
2021-02-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Class for all audio communications.
|
|
|
|
class udpAudio : public udpBase
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2022-01-23 15:06:31 +00:00
|
|
|
udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 lport, audioSetup rxSetup, audioSetup txSetup);
|
2021-02-05 17:40:58 +00:00
|
|
|
~udpAudio();
|
2021-02-08 08:31:48 +00:00
|
|
|
|
2021-05-27 10:41:08 +00:00
|
|
|
int audioLatency = 0;
|
|
|
|
|
2021-02-08 08:31:48 +00:00
|
|
|
signals:
|
2021-03-22 09:10:03 +00:00
|
|
|
void haveAudioData(audioPacket data);
|
2021-02-11 19:47:29 +00:00
|
|
|
|
2021-06-04 07:24:26 +00:00
|
|
|
void setupTxAudio(audioSetup setup);
|
|
|
|
void setupRxAudio(audioSetup setup);
|
2021-02-11 19:47:29 +00:00
|
|
|
|
2021-02-27 00:37:00 +00:00
|
|
|
void haveChangeLatency(quint16 value);
|
2021-03-22 18:53:34 +00:00
|
|
|
void haveSetVolume(unsigned char value);
|
2022-04-06 20:52:22 +00:00
|
|
|
void haveRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
|
|
|
void haveTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
2021-02-08 16:53:26 +00:00
|
|
|
|
|
|
|
public slots:
|
2021-02-27 00:37:00 +00:00
|
|
|
void changeLatency(quint16 value);
|
2021-03-22 18:53:34 +00:00
|
|
|
void setVolume(unsigned char value);
|
2022-04-06 20:52:22 +00:00
|
|
|
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
|
|
|
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
2022-04-10 22:13:51 +00:00
|
|
|
void receiveAudioData(audioPacket audio);
|
2021-02-11 19:18:35 +00:00
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
private:
|
|
|
|
|
2021-02-12 23:56:02 +00:00
|
|
|
void sendTxAudio();
|
2021-02-13 23:25:24 +00:00
|
|
|
void dataReceived();
|
2021-02-25 17:53:01 +00:00
|
|
|
void watchdog();
|
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
uint16_t sendAudioSeq = 0;
|
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
audioHandler* rxaudio = Q_NULLPTR;
|
|
|
|
QThread* rxAudioThread = Q_NULLPTR;
|
2021-02-08 08:31:48 +00:00
|
|
|
|
2021-03-22 09:10:03 +00:00
|
|
|
audioHandler* txaudio = Q_NULLPTR;
|
|
|
|
QThread* txAudioThread = Q_NULLPTR;
|
2021-02-10 17:32:56 +00:00
|
|
|
|
2022-04-10 22:13:51 +00:00
|
|
|
QTimer* txAudioTimer = Q_NULLPTR;
|
2021-06-06 21:11:48 +00:00
|
|
|
bool enableTx = true;
|
2021-02-12 23:56:02 +00:00
|
|
|
|
2021-11-15 19:28:44 +00:00
|
|
|
QMutex audioMutex;
|
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Class to handle the connection/disconnection of the radio.
|
|
|
|
class udpHandler: public udpBase
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2021-06-04 07:24:26 +00:00
|
|
|
udpHandler(udpPreferences prefs, audioSetup rxAudio, audioSetup txAudio);
|
2021-02-03 20:00:40 +00:00
|
|
|
~udpHandler();
|
|
|
|
|
2021-02-20 18:29:23 +00:00
|
|
|
bool streamOpened = false;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
udpCivData* civ = Q_NULLPTR;
|
|
|
|
udpAudio* audio = Q_NULLPTR;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
2022-01-21 19:23:32 +00:00
|
|
|
unsigned char numRadios;
|
|
|
|
QList<radio_cap_packet> radios;
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
void receiveDataFromUserToRig(QByteArray); // This slot will send data on to
|
2021-02-13 23:25:24 +00:00
|
|
|
void receiveFromCivStream(QByteArray);
|
2021-03-01 19:53:12 +00:00
|
|
|
void receiveAudioData(const audioPacket &data);
|
2021-02-27 00:37:00 +00:00
|
|
|
void changeLatency(quint16 value);
|
2021-03-22 18:53:34 +00:00
|
|
|
void setVolume(unsigned char value);
|
2021-02-21 14:53:42 +00:00
|
|
|
void init();
|
2022-01-23 17:54:40 +00:00
|
|
|
void setCurrentRadio(quint8 radio);
|
2022-04-06 20:52:22 +00:00
|
|
|
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
|
|
|
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under);
|
2022-01-21 23:58:18 +00:00
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
|
|
|
|
signals:
|
|
|
|
void haveDataFromPort(QByteArray data); // emit this when we have data, connect to rigcommander
|
2021-03-01 19:53:12 +00:00
|
|
|
void haveAudioData(audioPacket data); // emit this when we have data, connect to rigcommander
|
2021-02-04 19:53:48 +00:00
|
|
|
void haveNetworkError(QString, QString);
|
2021-02-27 00:37:00 +00:00
|
|
|
void haveChangeLatency(quint16 value);
|
2021-03-22 18:53:34 +00:00
|
|
|
void haveSetVolume(unsigned char value);
|
2022-01-22 15:12:36 +00:00
|
|
|
void haveNetworkStatus(networkStatus);
|
2021-05-21 15:30:52 +00:00
|
|
|
void haveBaudRate(quint32 baudrate);
|
2022-01-21 19:23:32 +00:00
|
|
|
void requestRadioSelection(QList<radio_cap_packet> radios);
|
2022-01-23 17:54:40 +00:00
|
|
|
void setRadioUsage(quint8, quint8 busy, QString name, QString mac);
|
2021-02-03 20:00:40 +00:00
|
|
|
private:
|
2021-02-20 18:29:23 +00:00
|
|
|
|
2021-02-14 07:53:55 +00:00
|
|
|
void sendAreYouThere();
|
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
void dataReceived();
|
|
|
|
|
2021-02-20 18:29:23 +00:00
|
|
|
void sendRequestStream();
|
2021-02-13 23:25:24 +00:00
|
|
|
void sendLogin();
|
|
|
|
void sendToken(uint8_t magic);
|
|
|
|
|
2021-02-03 20:00:40 +00:00
|
|
|
bool gotA8ReplyID = false;
|
|
|
|
bool gotAuthOK = false;
|
|
|
|
|
|
|
|
bool sentPacketLogin = false;
|
|
|
|
bool sentPacketConnect = false;
|
|
|
|
bool sentPacketConnect2 = false;
|
|
|
|
|
2021-02-07 17:40:38 +00:00
|
|
|
bool radioInUse = false;
|
|
|
|
|
2021-02-13 23:25:24 +00:00
|
|
|
quint16 controlPort;
|
|
|
|
quint16 civPort;
|
2021-02-13 23:28:28 +00:00
|
|
|
quint16 audioPort;
|
2021-02-13 23:25:24 +00:00
|
|
|
|
2022-01-23 15:06:31 +00:00
|
|
|
quint16 civLocalPort;
|
|
|
|
quint16 audioLocalPort;
|
|
|
|
|
2021-06-04 07:24:26 +00:00
|
|
|
audioSetup rxSetup;
|
|
|
|
audioSetup txSetup;
|
2021-03-01 20:31:05 +00:00
|
|
|
|
2021-02-08 16:53:26 +00:00
|
|
|
quint16 reauthInterval = 60000;
|
2021-02-21 01:18:14 +00:00
|
|
|
QString devName;
|
|
|
|
QString compName;
|
|
|
|
QString audioType;
|
|
|
|
//QByteArray replyId;
|
2021-02-20 18:29:23 +00:00
|
|
|
quint16 tokRequest;
|
|
|
|
quint32 token;
|
|
|
|
// These are for stream ident info.
|
2022-01-21 19:23:32 +00:00
|
|
|
quint8 macaddress[8];
|
2022-01-29 22:50:58 +00:00
|
|
|
quint8 guid[GUIDLEN];
|
2022-01-21 23:58:18 +00:00
|
|
|
bool useGuid = false;
|
2021-02-21 15:06:27 +00:00
|
|
|
QByteArray usernameEncoded;
|
|
|
|
QByteArray passwordEncoded;
|
|
|
|
|
2021-02-21 14:53:42 +00:00
|
|
|
QTimer* tokenTimer = Q_NULLPTR;
|
|
|
|
QTimer* areYouThereTimer = Q_NULLPTR;
|
2021-02-13 23:25:24 +00:00
|
|
|
|
2021-02-14 07:53:55 +00:00
|
|
|
bool highBandwidthConnection = false;
|
2021-05-18 08:32:56 +00:00
|
|
|
quint8 civId = 0;
|
|
|
|
quint16 rxSampleRates = 0;
|
|
|
|
quint16 txSampleRates = 0;
|
2022-01-22 15:12:36 +00:00
|
|
|
networkStatus status;
|
2022-04-18 19:29:50 +00:00
|
|
|
bool splitWf = false;
|
2021-02-03 20:00:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-02-03 22:10:37 +00:00
|
|
|
#endif
|