kopia lustrzana https://gitlab.com/eliggett/wfview
Merge remote-tracking branch 'origin/lan-alpha' into ui-enhance
commit
98d9c470c5
|
@ -616,6 +616,7 @@ void rigCommander::setCIVAddr(unsigned char civAddr)
|
|||
|
||||
void rigCommander::handleNewData(const QByteArray &data)
|
||||
{
|
||||
emit haveDataForServer(data);
|
||||
parseData(data);
|
||||
}
|
||||
|
||||
|
@ -2417,6 +2418,12 @@ void rigCommander::printHex(const QByteArray &pdata, bool printVert, bool printH
|
|||
qDebug() << "----- End hex dump -----";
|
||||
}
|
||||
|
||||
void rigCommander::dataFromServer(QByteArray data)
|
||||
{
|
||||
//qDebug() << "emit dataForComm()";
|
||||
emit dataForComm(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ public slots:
|
|||
void sayMode();
|
||||
void sayAll();
|
||||
void getDebug();
|
||||
void dataFromServer(QByteArray data);
|
||||
|
||||
signals:
|
||||
void commReady();
|
||||
|
@ -187,6 +188,7 @@ signals:
|
|||
void havePTTStatus(bool pttOn);
|
||||
void haveATUStatus(unsigned char status);
|
||||
void haveChangeBufferSize(quint16 value);
|
||||
void haveDataForServer(QByteArray outData);
|
||||
|
||||
|
||||
private:
|
||||
|
|
293
udphandler.cpp
293
udphandler.cpp
|
@ -63,7 +63,7 @@ udpHandler::udpHandler(QString ip, quint16 controlPort, quint16 civPort, quint16
|
|||
connect(&tokenTimer, &QTimer::timeout, this, std::bind(&udpHandler::sendToken, this, 0x05));
|
||||
connect(&areYouThereTimer, &QTimer::timeout, this, QOverload<>::of(&udpHandler::sendAreYouThere));
|
||||
connect(&pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
|
||||
connect(&idleTimer, &QTimer::timeout, this, std::bind(&udpBase::sendIdle, this, true, 0));
|
||||
connect(&idleTimer, &QTimer::timeout, this, std::bind(&udpBase::sendControl, this, true, 0, 0));
|
||||
|
||||
// Start sending are you there packets - will be stopped once "I am here" received
|
||||
areYouThereTimer.start(AREYOUTHERE_PERIOD);
|
||||
|
@ -287,47 +287,33 @@ void udpHandler::dataReceived()
|
|||
}
|
||||
|
||||
|
||||
|
||||
#define SERIALAUDIO_SIZE 0x90
|
||||
void udpHandler::sendRequestSerialAndAudio()
|
||||
{
|
||||
QByteArray usernameEncoded;
|
||||
passcode(username, usernameEncoded);
|
||||
int txSeqBufLengthMs = 50;
|
||||
|
||||
quint8 p[] = {
|
||||
0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
|
||||
0x00, 0x00, 0x00, 0x80, 0x01, 0x03, 0x00, static_cast<quint8>(authInnerSendSeq & 0xff), static_cast<quint8>(authInnerSendSeq >> 8 & 0xff), 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x01, 0x01, rxCodec, txCodec, 0x00, 0x00, static_cast<quint8>(rxSampleRate >> 8 & 0xff), static_cast<quint8>(rxSampleRate & 0xff),
|
||||
0x00, 0x00, static_cast<quint8>(txSampleRate >> 8 & 0xff), static_cast<quint8>(txSampleRate & 0xff),
|
||||
0x00, 0x00, static_cast<quint8>(civPort >> 8 & 0xff), static_cast<quint8>(civPort & 0xff),
|
||||
0x00, 0x00, static_cast<quint8>(audioPort >> 8 & 0xff), static_cast<quint8>(audioPort & 0xff), 0x00, 0x00,
|
||||
static_cast<quint8>(txSeqBufLengthMs >> 8 & 0xff), static_cast<quint8>(txSeqBufLengthMs & 0xff), 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
quint8 p[SERIALAUDIO_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(sizeof(p), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
memcpy(p + 0x13, QByteArrayLiteral("\x80\x01\x03").constData(), 3);
|
||||
qToLittleEndian(authInnerSendSeq, p + 0x16);
|
||||
memcpy(p + 0x1a, authId.constData(), authId.length());
|
||||
memcpy(p + 0x20, replyId.constData(), replyId.length());
|
||||
memcpy(p + 0x40, devName.constData(), devName.length());
|
||||
memcpy(p + 0x60, usernameEncoded.constData(), usernameEncoded.length());
|
||||
memcpy(p + 0x70, QByteArrayLiteral("\x01\x01").constData(), 2);
|
||||
p[0x72] = rxCodec;
|
||||
p[0x73] = txCodec;
|
||||
qToBigEndian(rxSampleRate, p + 0x76);
|
||||
qToBigEndian(txSampleRate, p + 0x7a);
|
||||
qToBigEndian(civPort, p + 0x7e);
|
||||
qToBigEndian(audioPort, p + 0x82);
|
||||
qToBigEndian(txSeqBufLengthMs, p + 0x86);
|
||||
p[0x88] = 0x01;
|
||||
|
||||
authInnerSendSeq++;
|
||||
|
||||
|
@ -342,11 +328,13 @@ void udpHandler::sendAreYouThere()
|
|||
qDebug() << this->metaObject()->className() << ": Radio not responding.";
|
||||
emit haveNetworkStatus("Radio not responding!");
|
||||
}
|
||||
qDebug() << this->metaObject()->className() << ": Sending Are You There...";
|
||||
|
||||
areYouThereCounter++;
|
||||
udpBase::sendAreYouThere();
|
||||
udpBase::sendControl(false,0x03,0x00);
|
||||
}
|
||||
|
||||
|
||||
#define LOGIN_SIZE 0x80
|
||||
void udpHandler::sendLogin() // Only used on control stream.
|
||||
{
|
||||
|
||||
|
@ -359,26 +347,14 @@ void udpHandler::sendLogin() // Only used on control stream.
|
|||
passcode(username, usernameEncoded);
|
||||
passcode(password, passwordEncoded);
|
||||
|
||||
quint8 p[] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, static_cast<quint8>(authInnerSendSeq & 0xff), static_cast<quint8>(authInnerSendSeq >> 8 & 0xff),
|
||||
0x00, static_cast<quint8>(authStartID & 0xff), static_cast<quint8>(authStartID >> 8 & 0xff), 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
quint8 p[LOGIN_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(sizeof(p), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
memcpy(p + 0x13, QByteArrayLiteral("\x70\x01").constData(), 2);
|
||||
qToLittleEndian(authInnerSendSeq, p + 0x17);
|
||||
qToLittleEndian(authStartID, p + 0x20);
|
||||
memcpy(p + 0x40, usernameEncoded.constData(), usernameEncoded.length());
|
||||
memcpy(p + 0x50, passwordEncoded.constData(), passwordEncoded.length());
|
||||
memcpy(p + 0x60, compName.constData(), compName.length());
|
||||
|
@ -388,23 +364,19 @@ void udpHandler::sendLogin() // Only used on control stream.
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
#define TOKEN_SIZE 0x40
|
||||
void udpHandler::sendToken(uint8_t magic)
|
||||
{
|
||||
|
||||
qDebug() << this->metaObject()->className() << "Sending Token request: " << magic;
|
||||
quint8 p[] = {
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0x00, 0x00, 0x00, 0x30, 0x01, static_cast<quint8>(magic), 0x00, static_cast<quint8>(authInnerSendSeq & 0xff), static_cast<quint8>((authInnerSendSeq) >> 8 & 0xff), 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
quint8 p[TOKEN_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(sizeof(p), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
memcpy(p + 0x13, QByteArrayLiteral("\x30\x01").constData(), 2);
|
||||
qToLittleEndian(magic, p + 0x15);
|
||||
qToLittleEndian(authInnerSendSeq, p + 0x17);
|
||||
memcpy(p + 0x1a, authId.constData(), authId.length());
|
||||
|
||||
authInnerSendSeq++;
|
||||
|
@ -426,13 +398,13 @@ udpCivData::udpCivData(QHostAddress local, QHostAddress ip, quint16 civPort)
|
|||
|
||||
QUdpSocket::connect(udp, &QUdpSocket::readyRead, this, &udpCivData::dataReceived);
|
||||
|
||||
sendAreYouThere(); // First connect packet
|
||||
sendControl(false, 0x03, 0x00); // First connect packet
|
||||
|
||||
/*
|
||||
Connect various timers
|
||||
*/
|
||||
connect(&pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
|
||||
connect(&idleTimer, &QTimer::timeout, this, std::bind(&udpBase::sendIdle, this, true, 0));
|
||||
connect(&idleTimer, &QTimer::timeout, this, std::bind(&udpBase::sendControl, this, true, 0, 0));
|
||||
|
||||
// send ping packets every 100 ms (maybe change to less frequent?)
|
||||
pingTimer.start(PING_PERIOD);
|
||||
|
@ -444,16 +416,20 @@ udpCivData::~udpCivData() {
|
|||
sendOpenClose(true);
|
||||
}
|
||||
|
||||
#define CIV_SIZE 0x15
|
||||
void udpCivData::send(QByteArray d)
|
||||
{
|
||||
// qDebug() << "Sending: (" << d.length() << ") " << d;
|
||||
|
||||
uint16_t l = d.length();
|
||||
const quint8 p[] = { static_cast<quint8>(0x15 + l), 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0xc1, static_cast<quint8>(l), 0x00, static_cast<quint8>(sendSeqB & 0xff),static_cast<quint8>(sendSeqB >>8 & 0xff)
|
||||
};
|
||||
quint8 p[CIV_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian((quint16)sizeof(p) + d.length(), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
p[0x10] = 0xc1;
|
||||
qToLittleEndian((quint16)d.length(), p + 0x11);
|
||||
qToBigEndian(sendSeqB, p + 0x13); // THIS IS BIG ENDIAN!
|
||||
|
||||
QByteArray t = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
t.append(d);
|
||||
sendTrackedPacket(t);
|
||||
|
@ -462,28 +438,7 @@ void udpCivData::send(QByteArray d)
|
|||
}
|
||||
|
||||
|
||||
|
||||
void udpCivData::SendIdle()
|
||||
{
|
||||
const quint8 p[] = { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
|
||||
sendTrackedPacket(QByteArray::fromRawData((const char*)p, sizeof(p)));
|
||||
}
|
||||
|
||||
void udpCivData::SendPeriodic()
|
||||
{
|
||||
const quint8 p[] = { 0x15, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
|
||||
sendTrackedPacket(QByteArray::fromRawData((const char*)p, sizeof(p)));
|
||||
|
||||
}
|
||||
|
||||
#define OPENCLOSE_SIZE 0x16
|
||||
void udpCivData::sendOpenClose(bool close)
|
||||
{
|
||||
uint8_t magic = 0x05;
|
||||
|
@ -493,12 +448,14 @@ void udpCivData::sendOpenClose(bool close)
|
|||
magic = 0x00;
|
||||
}
|
||||
|
||||
const quint8 p[] = {
|
||||
0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0xc0, 0x01, 0x00, static_cast<quint8>(sendSeqB & 0xff), static_cast<quint8>(sendSeqB >>8 & 0xff),static_cast<quint8>(magic)
|
||||
};
|
||||
quint8 p[OPENCLOSE_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian((quint16)sizeof(p), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
memcpy(p + 0x10, QByteArrayLiteral("\xc0\x01").constData(), 2);
|
||||
qToLittleEndian(sendSeqB, p + 0x13);
|
||||
p[0x15] = magic;
|
||||
|
||||
sendSeqB++;
|
||||
|
||||
|
@ -544,7 +501,7 @@ void udpCivData::dataReceived()
|
|||
quint8 temp = r[0] - 0x15;
|
||||
if ((quint8)r[16] == 0xc1 && (quint8)r[17] == temp)
|
||||
{
|
||||
emit receive(r.mid(21));
|
||||
emit receive(r.mid(0x15));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -626,7 +583,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
|
|||
|
||||
txAudioThread->start();
|
||||
|
||||
sendAreYouThere(); // No need to send periodic are you there as we know they are!
|
||||
sendControl(false, 0x03, 0x00); // First connect packet
|
||||
|
||||
connect(&pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
|
||||
pingTimer.start(PING_PERIOD); // send ping packets every 100ms
|
||||
|
@ -660,17 +617,15 @@ udpAudio::~udpAudio()
|
|||
|
||||
|
||||
|
||||
|
||||
#define TXAUDIO_SIZE 0x18
|
||||
void udpAudio::sendTxAudio()
|
||||
{
|
||||
quint8 p[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
//if (((txCodec == 0x01 || txCodec == 0x02) && audio.length() != 960) || (txCodec == 0x04 && audio.length() != 1920)) {
|
||||
// qDebug() << "Unsupported TX audio length :" << audio.length() << " With codec: " << txCodec;
|
||||
//}
|
||||
quint8 p[TXAUDIO_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
p[0x10] = 0x80;
|
||||
|
||||
if (txaudio->chunkAvailable) {
|
||||
QByteArray audio;
|
||||
txaudio->getNextAudioChunk(audio);
|
||||
|
@ -765,7 +720,7 @@ udpBase::~udpBase()
|
|||
{
|
||||
qDebug() << "Closing UDP stream :" << radioIP.toString() << ":" << port;
|
||||
if (udp != Q_NULLPTR) {
|
||||
sendPacketDisconnect();
|
||||
sendControl(false, 0x05, 0x00); // Send disconnect
|
||||
udp->close();
|
||||
delete udp;
|
||||
}
|
||||
|
@ -792,7 +747,7 @@ void udpBase::dataReceived(QByteArray r)
|
|||
areYouThereCounter = 0;
|
||||
// I don't think that we will ever receive an "I am here" other than in response to "Are you there?"
|
||||
remoteId = qFromLittleEndian<quint32>(r.mid(8, 4));
|
||||
sendAreYouReady();
|
||||
sendControl(false,0x06,0x01); // Send Are you ready - untracked.
|
||||
}
|
||||
else if (r.mid(0, 6) == QByteArrayLiteral("\x10\x00\x00\x00\x00\x00")) {
|
||||
// Just get the seqnum and ignore the rest.
|
||||
|
@ -818,7 +773,7 @@ void udpBase::dataReceived(QByteArray r)
|
|||
{
|
||||
// Packet was not found in buffer
|
||||
//qDebug() << this->metaObject()->className() << ": Could not find requested packet " << gotSeq << ", sending idle.";
|
||||
sendIdle(false, gotSeq);
|
||||
sendControl(false, 0, gotSeq);
|
||||
}
|
||||
}
|
||||
else if (r.mid(0, 6) == QByteArrayLiteral("\x18\x00\x00\x00\x01\x00"))
|
||||
|
@ -843,7 +798,7 @@ void udpBase::dataReceived(QByteArray r)
|
|||
if (!found)
|
||||
{
|
||||
//qDebug() << this->metaObject()->className() << ": Could not find requested packet " << gotSeq << ", sending idle.";
|
||||
sendIdle(false, gotSeq);
|
||||
sendControl(false, 0, gotSeq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -856,18 +811,24 @@ void udpBase::dataReceived(QByteArray r)
|
|||
// It is a ping request/response
|
||||
uint16_t gotSeq = qFromLittleEndian<quint16>(r.mid(6, 2));
|
||||
|
||||
if (r[16] == (char)0x00)
|
||||
if (r[0x10] == (char)0x00)
|
||||
{
|
||||
quint8 p[0x15];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(sizeof(p), p + 0x00);
|
||||
p[0x04] = 0x07;
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
p[0x10] = (char)0x01;
|
||||
p[0x11] = (char)r[0x11];
|
||||
p[0x12] = (char)r[0x12];
|
||||
p[0x13] = (char)r[0x13];
|
||||
p[0x14] = (char)r[0x14];
|
||||
|
||||
const quint8 p[] = { 0x15, 0x00, 0x00, 0x00, 0x07, 0x00,static_cast<quint8>(gotSeq & 0xff),static_cast<quint8>((gotSeq >> 8) & 0xff),
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0x01,static_cast<quint8>(r[17]),static_cast<quint8>(r[18]),static_cast<quint8>(r[19]),static_cast<quint8>(r[20])
|
||||
};
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
else if (r[0x10] == (char)0x01) {
|
||||
if (gotSeq == pingSendSeq)
|
||||
{
|
||||
// This is response to OUR request so increment counter
|
||||
|
@ -892,17 +853,20 @@ void udpBase::dataReceived(QByteArray r)
|
|||
|
||||
}
|
||||
|
||||
void udpBase::sendIdle(bool tracked=true,quint16 seq=0)
|
||||
#define CONTROL_SIZE 0x10
|
||||
// Used to send idle and other "control" style messages
|
||||
void udpBase::sendControl(bool tracked=true, quint8 id=0, quint16 seq=0)
|
||||
{
|
||||
quint8 p[] = { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
quint8 p[CONTROL_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian((quint16)sizeof(p), p + 0x00);
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
p[0x04] = id;
|
||||
|
||||
lastControlPacketSentTime = QDateTime::currentDateTime(); // Is this used?
|
||||
if (!tracked) {
|
||||
p[6] = seq & 0xff;
|
||||
p[7] = (seq >> 8) & 0xff;
|
||||
qToLittleEndian(seq, p + 0x06);
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
}
|
||||
|
@ -915,17 +879,19 @@ void udpBase::sendIdle(bool tracked=true,quint16 seq=0)
|
|||
return;
|
||||
}
|
||||
|
||||
#define PING_SIZE 0x15
|
||||
// Send periodic ping packets
|
||||
void udpBase::sendPing()
|
||||
{
|
||||
//qDebug() << this->metaObject()->className() << " tx buffer size:" << txSeqBuf.length();
|
||||
quint32 pingSeq = (quint32)((quint8)(rand() & 0xff)) | (quint16)innerSendSeq << 8 | (quint8)0x06 << 24;
|
||||
|
||||
const quint8 p[] = { 0x15, 0x00, 0x00, 0x00, 0x07, 0x00, static_cast<quint8>(pingSendSeq & 0xff),static_cast<quint8>(pingSendSeq >> 8 & 0xff),
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff),
|
||||
0x00, static_cast<quint8>(rand()),static_cast<quint8>(innerSendSeq & 0xff),static_cast<quint8>(innerSendSeq >> 8 & 0xff), 0x06
|
||||
};
|
||||
//qDebug() << this->metaObject()->className() << ": Send pkt7: " << QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
quint8 p[PING_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian((quint16)sizeof(p), p + 0x00);
|
||||
p[0x04] = 0x07;
|
||||
qToLittleEndian(myId, p + 0x08);
|
||||
qToLittleEndian(remoteId, p + 0x0c);
|
||||
qToLittleEndian(pingSeq, p + 0x11);
|
||||
lastPingSentTime = QDateTime::currentDateTime();
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
|
@ -967,55 +933,6 @@ void udpBase::purgeOldEntries()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This function is used by all sockets and expects an "I am here" response.
|
||||
/// </summary>
|
||||
void udpBase::sendAreYouThere()
|
||||
{
|
||||
qDebug() << this->metaObject()->className() << ": Sending Are You There...";
|
||||
const quint8 p[] = { 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Once an "I am here" response is received, send this
|
||||
/// </summary>
|
||||
void udpBase::sendAreYouReady()
|
||||
{
|
||||
qDebug() << this->metaObject()->className() << ": Sending Are you ready?";
|
||||
const quint8 p[] = { 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
return;
|
||||
}
|
||||
|
||||
void udpBase::sendPacketDisconnect() // Unmanaged packet
|
||||
{
|
||||
qDebug() << "Sending Stream Disconnect";
|
||||
|
||||
const quint8 p[] = { 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
static_cast<quint8>(myId & 0xff), static_cast<quint8>(myId >> 8 & 0xff), static_cast<quint8>(myId >> 16 & 0xff), static_cast<quint8>(myId >> 24 & 0xff),
|
||||
static_cast<quint8>(remoteId & 0xff), static_cast<quint8>(remoteId >> 8 & 0xff), static_cast<quint8>(remoteId >> 16 & 0xff), static_cast<quint8>(remoteId >> 24 & 0xff)
|
||||
};
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
udp->writeDatagram(QByteArray::fromRawData((const char*)p, sizeof(p)), radioIP, port);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// passcode function used to generate secure (ish) code
|
||||
/// </summary>
|
||||
|
|
|
@ -43,9 +43,8 @@ public:
|
|||
void init();
|
||||
|
||||
void dataReceived(QByteArray r);
|
||||
void sendAreYouThere();
|
||||
void sendPing(); // Periodic type 0x07 ping packet sending
|
||||
void sendIdle(bool tracked, quint16 seq);
|
||||
void sendControl(bool tracked,quint8 id, quint16 seq);
|
||||
|
||||
QUdpSocket* udp=Q_NULLPTR;
|
||||
uint32_t myId = 0;
|
||||
|
@ -80,8 +79,6 @@ public:
|
|||
QList <SEQBUFENTRY> txSeqBuf = QList<SEQBUFENTRY>();
|
||||
std::vector< quint16 > rxSeqBuf;
|
||||
|
||||
void sendAreYouReady();
|
||||
void sendPacketDisconnect();
|
||||
void sendTrackedPacket(QByteArray d);
|
||||
void purgeOldEntries();
|
||||
|
||||
|
@ -121,8 +118,6 @@ public slots:
|
|||
|
||||
private:
|
||||
void dataReceived();
|
||||
void SendIdle();
|
||||
void SendPeriodic();
|
||||
void sendOpenClose(bool close);
|
||||
};
|
||||
|
||||
|
|
234
udpserver.cpp
234
udpserver.cpp
|
@ -1,5 +1,7 @@
|
|||
#include "udpserver.h"
|
||||
|
||||
#define STALE_CONNECTION 15
|
||||
|
||||
udpServer::udpServer(SERVERCONFIG config) :
|
||||
config(config)
|
||||
{
|
||||
|
@ -53,30 +55,53 @@ udpServer::~udpServer()
|
|||
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
if (client->wdTimer != Q_NULLPTR) {
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
}
|
||||
delete client;
|
||||
controlClients.removeAll(client);
|
||||
}
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
delete client;
|
||||
civClients.removeAll(client);
|
||||
}
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
delete client;
|
||||
audioClients.removeAll(client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (udpControl != Q_NULLPTR) {
|
||||
udpControl->close();
|
||||
delete udpControl;
|
||||
|
@ -101,11 +126,17 @@ void udpServer::controlReceived()
|
|||
QNetworkDatagram datagram = udpControl->receiveDatagram();
|
||||
QByteArray r = datagram.data();
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -126,13 +157,13 @@ void udpServer::controlReceived()
|
|||
current->pingTimer = new QTimer();
|
||||
current->idleTimer = new QTimer();
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &controlClients, current, (quint16)0x00, false));
|
||||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendIdle, this, current, (quint16)0x00));
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::sendWatchdog, this, current));
|
||||
current->pingTimer->start(100);
|
||||
current->idleTimer->start(100);
|
||||
current->wdTimer->start(10000);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New Control connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
controlClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -164,12 +195,8 @@ void udpServer::controlReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->idleTimer->stop();
|
||||
current->pingTimer->stop();
|
||||
current->wdTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
|
||||
//current->wdTimer->stop(); // Keep watchdog running to delete stale connection.
|
||||
deleteConnection(&controlClients, current);
|
||||
}
|
||||
break;
|
||||
case (0x14):
|
||||
|
@ -183,11 +210,11 @@ void udpServer::controlReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&controlClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
current->pingSeq++;
|
||||
}
|
||||
else {
|
||||
|
@ -281,11 +308,20 @@ void udpServer::civReceived()
|
|||
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -303,11 +339,11 @@ void udpServer::civReceived()
|
|||
current->pingTimer = new QTimer();
|
||||
current->idleTimer = new QTimer();
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &civClients, current, (quint16)0x00, false));
|
||||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendIdle, this, current, (quint16)0x00));
|
||||
current->pingTimer->start(100);
|
||||
current->idleTimer->start(100);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New CIV connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
civClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -330,7 +366,7 @@ void udpServer::civReceived()
|
|||
} // This is a retransmit request
|
||||
else if (r.mid(0, 6) == QByteArrayLiteral("\x10\x00\x00\x00\x01\x00"))
|
||||
{
|
||||
// Just send an idle for now!
|
||||
// Just send an idle for now, we need to be able to retransmit missing packets.
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'retransmit' request for " << gotSeq;
|
||||
sendIdle(current, gotSeq);
|
||||
|
||||
|
@ -339,10 +375,7 @@ void udpServer::civReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->idleTimer->stop();
|
||||
current->pingTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
deleteConnection(&civClients, current);
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -357,11 +390,11 @@ void udpServer::civReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&civClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
current->pingSeq++;
|
||||
}
|
||||
else {
|
||||
|
@ -371,6 +404,17 @@ void udpServer::civReceived()
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (r.length() > 21) {
|
||||
// First check if we are missing any packets?
|
||||
quint8 temp = r[0] - 0x15;
|
||||
if ((quint8)r[16] == 0xc1 && (quint8)r[17] == temp)
|
||||
{
|
||||
//qDebug() << "Got CIV from server: " << r.mid(21);
|
||||
emit haveDataFromServer(r.mid(21));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -383,11 +427,19 @@ void udpServer::audioReceived()
|
|||
QByteArray r = datagram.data();
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
if (client != Q_NULLPTR && client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -403,9 +455,9 @@ void udpServer::audioReceived()
|
|||
current->innerPingSeq = (quint16)rand();
|
||||
current->pingSeq = (quint8)rand() << 8 | (quint8)rand();
|
||||
current->pingTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &audioClients, current, (quint16)0x00, false));
|
||||
current->pingTimer->start(100);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New Audio connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
audioClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -437,10 +489,7 @@ void udpServer::audioReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->pingTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
|
||||
deleteConnection(&audioClients, current);
|
||||
}
|
||||
break;
|
||||
case (0x14):
|
||||
|
@ -454,9 +503,9 @@ void udpServer::audioReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&audioClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
current->pingSeq++;
|
||||
|
@ -516,6 +565,8 @@ void udpServer::sendIAmReady(CLIENT* c)
|
|||
|
||||
void udpServer::sendIdle(CLIENT* c, quint16 seq)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (seq == 0x00)
|
||||
{
|
||||
seq = c->txSeq;
|
||||
|
@ -537,8 +588,20 @@ void udpServer::sendIdle(CLIENT* c, quint16 seq)
|
|||
|
||||
|
||||
#define PING_SIZE 0x15
|
||||
void udpServer::sendPing(CLIENT* c, quint16 seq, bool reply)
|
||||
void udpServer::sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
// Also use to detect "stale" connections
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
if (c->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
{
|
||||
qDebug() << "Deleting stale connection " << c->ipAddress.toString();
|
||||
deleteConnection(l, c);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//qDebug() << c->ipAddress.toString() << ": Sending Ping";
|
||||
|
||||
quint32 pingSeq = 0;
|
||||
|
@ -704,8 +767,11 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
|
|||
#define WATCHDOG_SIZE 0x14
|
||||
void udpServer::sendWatchdog(CLIENT* c)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
qint32 deciSeconds = (qint32)c->timeConnected.msecsTo(now)/100;
|
||||
|
||||
qint32 deciSeconds = (qint32)c->timeConnected.msecsTo(now) / 100;
|
||||
|
||||
quint8 p[WATCHDOG_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
|
@ -726,6 +792,8 @@ void udpServer::sendWatchdog(CLIENT* c)
|
|||
|
||||
void udpServer::sendStatus(CLIENT* c)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
qDebug() << c->ipAddress.toString() << ": Sending Status";
|
||||
|
||||
quint8 p[STATUS_SIZE];
|
||||
|
@ -758,3 +826,69 @@ void udpServer::sendStatus(CLIENT* c)
|
|||
|
||||
}
|
||||
|
||||
|
||||
#define SEND_SIZE 0x15
|
||||
void udpServer::dataForServer(QByteArray d)
|
||||
{
|
||||
|
||||
//qDebug() << "Server got:" << d;
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
if (client != Q_NULLPTR && client->connected) {
|
||||
quint8 p[SEND_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(client->txSeq, p + 0x06);
|
||||
qToLittleEndian(client->myId, p + 0x08);
|
||||
qToLittleEndian(client->remoteId, p + 0x0c);
|
||||
p[0x10] = (char)0xc1;
|
||||
qToLittleEndian((quint16)d.length(), p + 0x11);
|
||||
qToBigEndian(client->connSeq, p + 0x13); // THIS IS BIG ENDIAN!
|
||||
|
||||
QByteArray t = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
qToLittleEndian((quint16)t.length()+d.length(), p + 0x00);
|
||||
|
||||
t.append(d);
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
client->connSeq++;
|
||||
client->txSeq++;
|
||||
client->socket->writeDatagram(t, client->ipAddress, client->port);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// This function is passed a pointer to the list of connection objects and a pointer to the object itself
|
||||
// Needs to stop and delete all timers, remove the connection from the list and delete the connection.
|
||||
void udpServer::deleteConnection(QList<CLIENT*> *l, CLIENT* c)
|
||||
{
|
||||
qDebug() << "Deleting connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
|
||||
if (c->idleTimer != Q_NULLPTR) {
|
||||
c->idleTimer->stop();
|
||||
delete c->idleTimer;
|
||||
}
|
||||
if (c->pingTimer != Q_NULLPTR) {
|
||||
c->pingTimer->stop();
|
||||
delete c->pingTimer;
|
||||
}
|
||||
if (c->wdTimer != Q_NULLPTR) {
|
||||
c->wdTimer->stop();
|
||||
delete c->wdTimer;
|
||||
}
|
||||
|
||||
QList<CLIENT*>::iterator it = l->begin();
|
||||
while (it != l->end()) {
|
||||
CLIENT* client = *it;
|
||||
if (client != Q_NULLPTR && client == c) {
|
||||
it = l->erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
delete c; // Is this needed or will the erase have done it?
|
||||
c = Q_NULLPTR;
|
||||
qDebug() << "Current Number of clients connected: " << l->length();
|
||||
}
|
||||
|
|
12
udpserver.h
12
udpserver.h
|
@ -31,6 +31,10 @@ public:
|
|||
|
||||
public slots:
|
||||
void init();
|
||||
void dataForServer(QByteArray);
|
||||
|
||||
signals:
|
||||
void haveDataFromServer(QByteArray);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -71,6 +75,8 @@ private:
|
|||
quint8 txCodec;
|
||||
quint16 rxSampleRate;
|
||||
quint16 txSampleRate;
|
||||
|
||||
|
||||
};
|
||||
|
||||
void controlReceived();
|
||||
|
@ -78,7 +84,7 @@ private:
|
|||
void audioReceived();
|
||||
void sendIAmHere(CLIENT* c);
|
||||
void sendIAmReady(CLIENT* c);
|
||||
void sendPing(CLIENT* c, quint16 seq, bool reply);
|
||||
void sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply);
|
||||
void sendIdle(CLIENT* c, quint16 seq);
|
||||
void sendLoginResponse(CLIENT* c, quint16 seq, bool allowed);
|
||||
void sendCapabilities(CLIENT* c);
|
||||
|
@ -86,6 +92,8 @@ private:
|
|||
void sendTokenResponse(CLIENT* c,quint8 type);
|
||||
void sendWatchdog(CLIENT* c);
|
||||
void sendStatus(CLIENT* c);
|
||||
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -109,6 +117,8 @@ private:
|
|||
QByteArray data;
|
||||
};
|
||||
|
||||
QMutex mutex; // Used for critical operations.
|
||||
|
||||
QList <CLIENT*> controlClients = QList<CLIENT*>();
|
||||
QList <CLIENT*> civClients = QList<CLIENT*>();
|
||||
QList <CLIENT*> audioClients = QList<CLIENT*>();
|
||||
|
|
|
@ -201,6 +201,8 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent
|
|||
|
||||
connect(this, SIGNAL(initServer()), udp, SLOT(init()));
|
||||
connect(serverThread, SIGNAL(finished()), udp, SLOT(deleteLater()));
|
||||
|
||||
|
||||
serverThread->start();
|
||||
|
||||
emit initServer();
|
||||
|
@ -374,6 +376,12 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent
|
|||
// Metering
|
||||
connect(this, SIGNAL(getMeters(bool)), rig, SLOT(getMeters(bool)));
|
||||
|
||||
|
||||
// Server
|
||||
connect(rig, SIGNAL(haveDataForServer(QByteArray)), udp, SLOT(dataForServer(QByteArray)));
|
||||
connect(udp, SIGNAL(haveDataFromServer(QByteArray)), rig, SLOT(dataFromServer(QByteArray)));
|
||||
|
||||
|
||||
ui->plot->addGraph(); // primary
|
||||
ui->plot->addGraph(0, 0); // secondary, peaks, same axis as first?
|
||||
ui->waterfall->addGraph();
|
||||
|
|
Ładowanie…
Reference in New Issue