From 4e6d4d5faacad445af1cfd82191ccc102280d01d Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Sun, 21 Feb 2021 01:18:14 +0000 Subject: [PATCH] Some more packet type fixes and make it not disconnect other users from the radio. --- packettypes.h | 21 ++++++++++- udphandler.cpp | 97 ++++++++++++++++++++++++-------------------------- udphandler.h | 8 ++--- 3 files changed, 70 insertions(+), 56 deletions(-) diff --git a/packettypes.h b/packettypes.h index fb7637e..7a81842 100644 --- a/packettypes.h +++ b/packettypes.h @@ -35,6 +35,7 @@ typedef union control_packet { // 0x15 length ping packet +// Also used for the slightly different civ header packet. typedef union ping_packet { struct { @@ -58,6 +59,24 @@ typedef union ping_packet { char packet[PING_SIZE]; } *ping_packet_t, * data_packet_t, data_packet; +// 0x16 length open/close packet +typedef union openclose_packet { + struct + { + quint32 len; // 0x00 + quint16 type; // 0x04 + quint16 seq; // 0x06 + quint32 sentid; // 0x08 + quint32 rcvdid; // 0x0c + quint16 data; // 0x10 + char unused; // 0x11 + quint16 sendseq; //0x13 + char magic; // 0x15 + + }; + char packet[OPENCLOSE_SIZE]; +} *startstop_packet_t; + // 0x18 length txaudio packet typedef union txaudio_packet { @@ -218,7 +237,7 @@ typedef union conninfo_packet { char unusedg[16]; // 0x50 union { // This contains differences between the send/receive packet struct { // Receive - quint32 ready; // 0x60 + quint32 busy; // 0x60 char computer[16]; // 0x64 char unusedi[16]; // 0x74 quint32 ipaddress; // 0x84 diff --git a/udphandler.cpp b/udphandler.cpp index de9872a..464434b 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -69,13 +69,13 @@ udpHandler::udpHandler(QString ip, quint16 controlPort, quint16 civPort, quint16 areYouThereTimer.start(AREYOUTHERE_PERIOD); // Set my computer name. Should this be configurable? - compName = QString("wfview").toUtf8(); + compName = "wfview"; } udpHandler::~udpHandler() { - if (isAuthenticated) { + if (streamOpened) { if (audio != Q_NULLPTR) { delete audio; } @@ -83,7 +83,6 @@ udpHandler::~udpHandler() if (civ != Q_NULLPTR) { delete civ; } - qDebug() << "Sending token removal packet"; sendToken(0x01); } @@ -235,52 +234,50 @@ void udpHandler::dataReceived() highBandwidthConnection = true; } - qDebug() << this->metaObject()->className() << ": Detected connection speed " << QString::fromUtf8(parseNullTerminatedString(r, 0x40)); + qDebug() << this->metaObject()->className() << ": Detected connection speed " << in->connection; break; } case (CONNINFO_SIZE): { conninfo_packet_t in = (conninfo_packet_t)r.constData(); - if (!streamOpened && !in->ready) + devName = in->name; + QHostAddress ip = QHostAddress(qToBigEndian(in->ipaddress)); + if (!streamOpened && in->busy) { - devName = parseNullTerminatedString(in->computer,0x00); - QHostAddress ip = QHostAddress(in->ipaddress); - if (!ip.isEqual(QHostAddress("0.0.0.0")) && parseNullTerminatedString(r, 0x64) != compName) // || ip != localIP ) // TODO: More testing of IP address detection code! + if (strcmp(in->computer,compName.toLocal8Bit())) { - emit haveNetworkStatus(QString::fromUtf8(devName) + "in use by: " + QString::fromUtf8(parseNullTerminatedString(r, 0x64)) + " (" + ip.toString() + ")"); + emit haveNetworkStatus(devName + " in use by: " + in->computer + " (" + ip.toString() + ")"); sendControl(false, 0x00, in->seq); // Respond with an idle } else { - emit haveNetworkStatus(QString::fromUtf8(devName) + " available"); + civ = new udpCivData(localIP, radioIP, civPort); + audio = new udpAudio(localIP, radioIP, audioPort, rxBufferSize, rxSampleRate, rxCodec, txSampleRate, txCodec); - identa = in->identa; - identb = in->identb; + QObject::connect(civ, SIGNAL(receive(QByteArray)), this, SLOT(receiveFromCivStream(QByteArray))); + QObject::connect(this, SIGNAL(haveChangeBufferSize(quint16)), audio, SLOT(changeBufferSize(quint16))); - sendRequestStream(); + streamOpened = true; + + emit haveNetworkStatus(devName); + + qDebug() << this->metaObject()->className() << "Got serial and audio request success, device name: " << devName; + + // Stuff can change in the meantime because of a previous login... + remoteId = in->sentid; + myId = in->rcvdid; + tokRequest = in->tokrequest; + token = in->token; } } - else if (!streamOpened && in->ready) + else if (!streamOpened && !in->busy) { - devName = parseNullTerminatedString(in->computer, 0); - - civ = new udpCivData(localIP, radioIP, civPort); - audio = new udpAudio(localIP, radioIP, audioPort, rxBufferSize, rxSampleRate, rxCodec, txSampleRate, txCodec); - - QObject::connect(civ, SIGNAL(receive(QByteArray)), this, SLOT(receiveFromCivStream(QByteArray))); - QObject::connect(this, SIGNAL(haveChangeBufferSize(quint16)), audio, SLOT(changeBufferSize(quint16))); - - streamOpened = true; - - emit haveNetworkStatus(QString::fromUtf8(devName)); - - qDebug() << this->metaObject()->className() << "Got serial and audio request success, device name: " << QString::fromUtf8(devName); - - // Stuff can change in the meantime because of a previous login... - remoteId = in->sentid; - myId = in->rcvdid; - tokRequest = in->tokrequest; - token = in->token; + emit haveNetworkStatus(devName + " available"); + + identa = in->identa; + identb = in->identb; + + sendRequestStream(); } break; } @@ -288,12 +285,12 @@ void udpHandler::dataReceived() case (CAPABILITIES_SIZE): { capabilities_packet_t in = (capabilities_packet_t)r.constData(); - audioType = parseNullTerminatedString(in->audio, 0); - devName = parseNullTerminatedString(in->name, 0); + audioType = in->audio; + devName = in->name; //replyId = r.mid(0x42, 16); qDebug() << this->metaObject()->className() << "Received radio capabilities, Name:" << - QString::fromUtf8(devName) << " Audio:" << - QString::fromUtf8(audioType); + devName << " Audio:" << + audioType; break; } @@ -328,7 +325,7 @@ void udpHandler::sendRequestStream() p.innerseq = authInnerSendSeq; p.tokrequest = tokRequest; p.token = token; - memcpy(&p.name, devName.constData(), devName.length()); + memcpy(&p.name, devName.toLocal8Bit().constData(), devName.length()); p.rxenable = 1; p.txenable = 1; p.rxcodec = rxCodec; @@ -381,7 +378,7 @@ void udpHandler::sendLogin() // Only used on control stream. p.tokrequest = tokRequest; memcpy(p.username, usernameEncoded.constData(), usernameEncoded.length()); memcpy(p.password, passwordEncoded.constData(), passwordEncoded.length()); - memcpy(p.name, compName.constData(), compName.length()); + memcpy(p.name, compName.toLocal8Bit().constData(), compName.length()); authInnerSendSeq++; sendTrackedPacket(QByteArray::fromRawData((const char*)p.packet, sizeof(p))); @@ -469,18 +466,18 @@ void udpCivData::sendOpenClose(bool close) magic = 0x00; } - 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; + openclose_packet p; + memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! + p.len = sizeof(p); + p.sentid = myId; + p.rcvdid = remoteId; + p.data = 0x01c0; // Not sure what other values are available: + p.sendseq = qToBigEndian(sendSeqB); + p.magic = magic; sendSeqB++; - sendTrackedPacket(QByteArray::fromRawData((const char*)p, sizeof(p))); + sendTrackedPacket(QByteArray::fromRawData((const char*)p.packet, sizeof(p))); return; } @@ -613,7 +610,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint connect(&pingTimer, &QTimer::timeout, this, &udpBase::sendPing); pingTimer.start(PING_PERIOD); // send ping packets every 100ms - + txAudioTimer.setTimerType(Qt::PreciseTimer); connect(&txAudioTimer, &QTimer::timeout, this, &udpAudio::sendTxAudio); txAudioTimer.start(TXAUDIO_PERIOD); @@ -987,8 +984,6 @@ void passcode(QString in, QByteArray& out) }; - quint8* res = new quint8[16]; - memset(res, 0, 16); // Make sure res buffer is empty! QByteArray ba = in.toLocal8Bit(); uchar* ascii = (uchar*)ba.constData(); for (int i = 0; i < in.length() && i < 16; i++) diff --git a/udphandler.h b/udphandler.h index b096d77..9f96ee5 100644 --- a/udphandler.h +++ b/udphandler.h @@ -234,10 +234,10 @@ private: quint8 txCodec; quint16 reauthInterval = 60000; - QByteArray devName; - QByteArray compName; - QByteArray audioType; - QByteArray replyId; + QString devName; + QString compName; + QString audioType; + //QByteArray replyId; quint16 tokRequest; quint32 token; // These are for stream ident info.