Various compatibility improvements

merge-requests/9/merge
Phil Taylor 2022-04-20 13:35:23 +01:00
rodzic d86f8958b2
commit 86502a5c3a
11 zmienionych plików z 273 dodań i 318 usunięć

Wyświetl plik

@ -125,6 +125,13 @@ bool audioHandler::init(audioSetup setupIn)
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "No channels found, aborting setup."; qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "No channels found, aborting setup.";
return false; return false;
} }
if (format.channelCount() == 1 && setup.format.channelCount() == 2) {
format.setChannelCount(2);
if (!setup.port.isFormatSupported(format)) {
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "Cannot request stereo input!";
format.setChannelCount(1);
}
}
if (format.sampleSize() == 24) { if (format.sampleSize() == 24) {
// We can't convert this easily // We can't convert this easily
@ -494,6 +501,13 @@ void audioHandler::getNextAudioChunk()
samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2); samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2);
samplesF = samplesTemp; samplesF = samplesTemp;
} }
else if (format.channelCount() == 1 && setup.format.channelCount() == 2) {
// Convert mono to stereo if required
Eigen::VectorXf samplesTemp(samplesF.size() * 2);
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data(), samplesF.size()) = samplesF;
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data() + 1, samplesF.size()) = samplesF;
samplesF = samplesTemp;
}
//qInfo(logAudio()) << "Sending audio len" << livePacket.data.length() << "remaining" << tempBuf.data.length() << "resampled" << samplesF.size(); //qInfo(logAudio()) << "Sending audio len" << livePacket.data.length() << "remaining" << tempBuf.data.length() << "resampled" << samplesF.size();

Wyświetl plik

@ -57,11 +57,11 @@ int main(int argc, char *argv[])
keyboard* kb = new keyboard(); keyboard* kb = new keyboard();
kb->start(); kb->start();
#else #else
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv); QApplication a(argc, argv);
a.setOrganizationName("wfview"); a.setOrganizationName("wfview");
a.setOrganizationDomain("wfview.org"); a.setOrganizationDomain("wfview.org");
a.setApplicationName("wfview"); a.setApplicationName("wfview");
a.setAttribute(Qt::AA_EnableHighDpiScaling);
#endif #endif
#ifdef QT_DEBUG #ifdef QT_DEBUG

Wyświetl plik

@ -121,6 +121,7 @@ typedef union audio_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
quint16 ident; // 0x10 quint16 ident; // 0x10
quint16 sendseq; // 0x12 quint16 sendseq; // 0x12
quint16 unused; // 0x14 quint16 unused; // 0x14
@ -165,18 +166,24 @@ typedef union token_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[3]; // 0x10 char unuseda[2]; // 0x10
quint16 code; // 0x13 quint16 payloadsize; // 0x12
quint16 res; // 0x15 quint8 requestreply; // 0x13
quint8 innerseq; // 0x17 quint8 requesttype; // 0x14
char unusedb; // 0x18 quint16 innerseq; // 0x16
char unusedc; // 0x19 char unusedb[2]; // 0x18
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
char unusedd[7]; // 0x20 union {
quint16 commoncap; // 0x27 struct {
char unuseddd; // 0x29 quint16 authstartid; // 0x20
char macaddress[6]; // 0x2a char unusedg[5]; // 0x22
quint16 commoncap; // 0x27
char unusedh; // 0x29
quint8 macaddress[6]; // 0x2a
};
quint8 guid[GUIDLEN]; // 0x20
};
quint32 response; // 0x30 quint32 response; // 0x30
char unusede[12]; // 0x34 char unusede[12]; // 0x34
}; };
@ -192,19 +199,24 @@ typedef union status_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[3]; // 0x10 char unuseda[2]; // 0x10
quint16 code; // 0x13 quint16 payloadsize; // 0x12
quint16 res; // 0x15 quint8 requestreply; // 0x13
quint8 innerseq; // 0x17 quint8 requesttype; // 0x14
char unusedb; // 0x18 quint16 innerseq; // 0x16
char unusedc; // 0x19 char unusedb[2]; // 0x18
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
char unusedd[6]; // 0x20 union {
quint16 unknown; // 0x26 struct {
char unusede; // 0x28 quint16 authstartid; // 0x20
char unusedf; // 0x29 char unusedd[5]; // 0x22
quint8 macaddress[6]; // 0x2a quint16 commoncap; // 0x27
char unusede; // 0x29
quint8 macaddress[6]; // 0x2a
};
quint8 guid[GUIDLEN]; // 0x20
};
quint32 error; // 0x30 quint32 error; // 0x30
char unusedg[12]; // 0x34 char unusedg[12]; // 0x34
char disc; // 0x40 char disc; // 0x40
@ -226,12 +238,12 @@ typedef union login_response_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[3]; // 0x10 char unuseda[2]; // 0x10
quint16 code; // 0x13 quint16 payloadsize; // 0x12
quint16 res; // 0x15 quint8 requestreply; // 0x13
quint8 innerseq; // 0x17 quint8 requesttype; // 0x14
char unusedb; // 0x18 quint16 innerseq; // 0x16
char unusedc; // 0x19 char unusedb[2]; // 0x18
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
quint16 authstartid; // 0x20 quint16 authstartid; // 0x20
@ -253,12 +265,12 @@ typedef union login_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[3]; // 0x10 char unuseda[2]; // 0x10
quint16 code; // 0x13 quint16 payloadsize; // 0x12
quint16 res; // 0x15 quint8 requestreply; // 0x13
quint8 innerseq; // 0x17 quint8 requesttype; // 0x14
char unusedaa; // 0x18; quint16 innerseq; // 0x16
char unusedb; // 0x19 char unusedb[2]; // 0x18
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
char unusedc[32]; // 0x20 char unusedc[32]; // 0x20
@ -279,12 +291,12 @@ typedef union conninfo_packet {
quint16 seq; // 0x06 quint16 seq; // 0x06
quint32 sentid; // 0x08 quint32 sentid; // 0x08
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[3]; // 0x10 char unuseda[2]; // 0x10
quint16 code; // 0x13 quint16 payloadsize; // 0x12
quint16 res; // 0x15 quint8 requestreply; // 0x13
quint8 innerseq; // 0x17 quint8 requesttype; // 0x14
char unusedaa; // 0x18 quint16 innerseq; // 0x16
char unusedb; // 0x19 char unusedb[2]; // 0x18
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
union { union {
@ -293,7 +305,7 @@ typedef union conninfo_packet {
char unusedg[5]; // 0x22 char unusedg[5]; // 0x22
quint16 commoncap; // 0x27 quint16 commoncap; // 0x27
char unusedh; // 0x29 char unusedh; // 0x29
char macaddress[6]; // 0x2a quint8 macaddress[6]; // 0x2a
}; };
quint8 guid[GUIDLEN]; // 0x20 quint8 guid[GUIDLEN]; // 0x20
}; };
@ -328,19 +340,18 @@ typedef union conninfo_packet {
// 0x64 length radio capabilities part of cap packet. // 0x64 length radio capabilities part of cap packet.
/*
};*/
typedef union radio_cap_packet { typedef union radio_cap_packet {
struct struct
{ {
union { union {
struct { struct {
char unusede[7]; // 0x0 quint8 unusede[7]; // 0x00
quint16 commoncap; // 0x0 quint16 commoncap; // 0x07
char unused; // 0x0 quint8 unused; // 0x09
char macaddress[6]; // 0x0 quint8 macaddress[6]; // 0x0a
}; };
quint8 guid[GUIDLEN]; // 0x0 quint8 guid[GUIDLEN]; // 0x0
}; };
char name[32]; // 0x10 char name[32]; // 0x10
char audio[32]; // 0x30 char audio[32]; // 0x30
@ -373,14 +384,14 @@ typedef union capabilities_packet {
quint32 rcvdid; // 0x0c quint32 rcvdid; // 0x0c
char unuseda[2]; // 0x10 char unuseda[2]; // 0x10
quint16 payloadsize; // 0x12 quint16 payloadsize; // 0x12
quint16 res; // 0x14 quint8 requestreply; // 0x13
quint8 requesttype; // 0x14
quint16 innerseq; // 0x16 quint16 innerseq; // 0x16
char unusedb; // 0x18 char unusedb[2]; // 0x18
char unusedc; // 0x19
quint16 tokrequest; // 0x1a quint16 tokrequest; // 0x1a
quint32 token; // 0x1c quint32 token; // 0x1c
char unusedd[33]; // 0x20 char unusedd[32]; // 0x20
char numradios; // 0x41 quint16 numradios; // 0x40
}; };
char packet[CAPABILITIES_SIZE]; char packet[CAPABILITIES_SIZE];
} *capabilities_packet_t; } *capabilities_packet_t;

Wyświetl plik

@ -1493,6 +1493,9 @@ void rigCommander::parseLevels()
{ {
switch(payloadIn[1]) switch(payloadIn[1])
{ {
case '\x01':
// noise or s-meter sequelch status
break;
case '\x02': case '\x02':
// S-Meter // S-Meter
emit haveMeter(meterS, level); emit haveMeter(meterS, level);
@ -1503,6 +1506,9 @@ void rigCommander::parseLevels()
emit haveMeter(meterCenter, level); emit haveMeter(meterCenter, level);
state.set(SMETER, level, false); state.set(SMETER, level, false);
break; break;
case '\x05':
// Various squelch (tone etc.)
break;
case '\x11': case '\x11':
// RF-Power meter // RF-Power meter
emit haveMeter(meterPower, level); emit haveMeter(meterPower, level);
@ -4709,7 +4715,7 @@ void rigCommander::printHex(const QByteArray &pdata, bool printVert, bool printH
void rigCommander::dataFromServer(QByteArray data) void rigCommander::dataFromServer(QByteArray data)
{ {
//qInfo(logRig()) << "emit dataForComm()"; //qInfo(logRig()) << "***************** emit dataForComm()" << data;
emit dataForComm(data); emit dataForComm(data);
} }

Wyświetl plik

@ -89,7 +89,7 @@ void servermain::openRig()
{ {
//qInfo(logSystem()) << "Got rig"; //qInfo(logSystem()) << "Got rig";
QMetaObject::invokeMethod(radio->rig, [=]() { QMetaObject::invokeMethod(radio->rig, [=]() {
radio->rig->commSetup(radio->civAddr, radio->serialPort, radio->baudRate, QString("none"),prefs.tcpPort); radio->rig->commSetup(radio->civAddr, radio->serialPort, radio->baudRate, QString("none"),prefs.tcpPort,0);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
} }
} }
@ -375,7 +375,7 @@ void servermain::setServerToPrefs()
udp = Q_NULLPTR; udp = Q_NULLPTR;
} }
udp = new udpServer(serverConfig, serverTxSetup, serverRxSetup); udp = new udpServer(serverConfig);
serverThread = new QThread(this); serverThread = new QThread(this);

Wyświetl plik

@ -223,7 +223,7 @@ void udpHandler::dataReceived()
case (TOKEN_SIZE): // Response to Token request case (TOKEN_SIZE): // Response to Token request
{ {
token_packet_t in = (token_packet_t)r.constData(); token_packet_t in = (token_packet_t)r.constData();
if (in->res == 0x05 && in->type != 0x01) if (in->requesttype == 0x05 && in->requestreply == 0x02 && in->type != 0x01)
{ {
if (in->response == 0x0000) if (in->response == 0x0000)
{ {
@ -374,8 +374,9 @@ void udpHandler::dataReceived()
qInfo(logUdp()) << "Got Connection status for:" << in->name << "Busy:" << in->busy << "Computer" << in->computer << "IP" << ip.toString(); qInfo(logUdp()) << "Got Connection status for:" << in->name << "Busy:" << in->busy << "Computer" << in->computer << "IP" << ip.toString();
// First we need to find this radio in our capabilities packet, there aren't many so just step through // First we need to find this radio in our capabilities packet, there aren't many so just step through
for (unsigned char f = 0; f < radios.length(); f++) for (unsigned char f = 0; f < radios.size(); f++)
{ {
if ((radios[f].commoncap == 0x8010 && if ((radios[f].commoncap == 0x8010 &&
radios[f].macaddress[0] == in->macaddress[0] && radios[f].macaddress[0] == in->macaddress[0] &&
radios[f].macaddress[1] == in->macaddress[1] && radios[f].macaddress[1] == in->macaddress[1] &&
@ -386,11 +387,15 @@ void udpHandler::dataReceived()
!memcmp(radios[f].guid,in->guid, GUIDLEN)) !memcmp(radios[f].guid,in->guid, GUIDLEN))
{ {
emit setRadioUsage(f, in->busy, QString(in->computer), ip.toString()); emit setRadioUsage(f, in->busy, QString(in->computer), ip.toString());
qDebug(logUdp()) << "Set radio usage num:" << f << in->name << "Busy:" << in->busy << "Computer" << in->computer << "IP" << ip.toString();
} }
} }
if (in->type != 0x01 && !streamOpened) {
if (in->busy && numRadios == 1) if (!streamOpened && radios.size()==1) {
qDebug(logUdp()) << "Single radio available, can I connect to it?";
if (in->busy)
{ {
if (in->ipaddress != 0x00 && strcmp(in->computer, compName.toLocal8Bit())) if (in->ipaddress != 0x00 && strcmp(in->computer, compName.toLocal8Bit()))
{ {
@ -400,17 +405,19 @@ void udpHandler::dataReceived()
else { else {
} }
} }
else if (!in->busy && numRadios == 1) else if (!in->busy)
{ {
qDebug(logUdp()) << "Attempting to connect to radio";
status.message = devName + " available"; status.message = devName + " available";
setCurrentRadio(0); setCurrentRadio(0);
} }
} }
else if (streamOpened) else if (streamOpened)
/* If another client connects/disconnects from the server, the server will emit /* If another client connects/disconnects from the server, the server will emit
a CONNINFO packet, send our details to confirm we still want the stream */ a CONNINFO packet, send our details to confirm we still want the stream */
{ {
//qDebug(logUdp()) << "I am already connected????";
// Received while stream is open. // Received while stream is open.
//sendRequestStream(); //sendRequestStream();
} }
@ -440,9 +447,16 @@ void udpHandler::dataReceived()
qInfo(logUdp()) << this->metaObject()->className() << "Received radio capabilities, Name:" << qInfo(logUdp()) << this->metaObject()->className() << "Received radio capabilities, Name:" <<
radio.name << " Audio:" << radio.name << " Audio:" <<
radio.audio << "CIV:" << hex << (unsigned char)radio.civ << radio.audio << "CIV:" << hex << (unsigned char)radio.civ <<
"MAC:" << radio.macaddress[0] <<
":" << radio.macaddress[1] <<
":" << radio.macaddress[2] <<
":" << radio.macaddress[3] <<
":" << radio.macaddress[4] <<
":" << radio.macaddress[5] <<
"CAPF" << radio.capf; "CAPF" << radio.capf;
} }
emit requestRadioSelection(radios); emit requestRadioSelection(radios);
break; break;
} }
@ -505,8 +519,10 @@ void udpHandler::sendRequestStream()
p.len = sizeof(p); p.len = sizeof(p);
p.sentid = myId; p.sentid = myId;
p.rcvdid = remoteId; p.rcvdid = remoteId;
p.code = 0x0180; p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.res = 0x03; p.requesttype = 0x03;
p.requestreply = 0x01;
if (!useGuid) { if (!useGuid) {
p.commoncap = 0x8010; p.commoncap = 0x8010;
memcpy(&p.macaddress, macaddress, 6); memcpy(&p.macaddress, macaddress, 6);
@ -514,7 +530,7 @@ void udpHandler::sendRequestStream()
else { else {
memcpy(&p.guid, guid, GUIDLEN); memcpy(&p.guid, guid, GUIDLEN);
} }
p.innerseq = authSeq++; p.innerseq = qToBigEndian(authSeq++);
p.tokrequest = tokRequest; p.tokrequest = tokRequest;
p.token = token; p.token = token;
memcpy(&p.name, devName.toLocal8Bit().constData(), devName.length()); memcpy(&p.name, devName.toLocal8Bit().constData(), devName.length());
@ -565,8 +581,11 @@ void udpHandler::sendLogin() // Only used on control stream.
p.len = sizeof(p); p.len = sizeof(p);
p.sentid = myId; p.sentid = myId;
p.rcvdid = remoteId; p.rcvdid = remoteId;
p.code = 0x0170; // Not sure what this is? p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.innerseq = authSeq++; p.requesttype = 0x00;
p.requestreply = 0x01;
p.innerseq = qToBigEndian(authSeq++);
p.tokrequest = tokRequest; p.tokrequest = tokRequest;
memcpy(p.username, usernameEncoded.constData(), usernameEncoded.length()); memcpy(p.username, usernameEncoded.constData(), usernameEncoded.length());
memcpy(p.password, passwordEncoded.constData(), passwordEncoded.length()); memcpy(p.password, passwordEncoded.constData(), passwordEncoded.length());
@ -585,9 +604,10 @@ void udpHandler::sendToken(uint8_t magic)
p.len = sizeof(p); p.len = sizeof(p);
p.sentid = myId; p.sentid = myId;
p.rcvdid = remoteId; p.rcvdid = remoteId;
p.code = 0x0130; // Not sure what this is? p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.res = magic; p.requesttype = magic;
p.innerseq = authSeq++; p.requestreply = 0x01;
p.innerseq = qToBigEndian(authSeq++);
p.tokrequest = tokRequest; p.tokrequest = tokRequest;
p.token = token; p.token = token;

Wyświetl plik

@ -85,7 +85,7 @@ public:
QUdpSocket* udp=Q_NULLPTR; QUdpSocket* udp=Q_NULLPTR;
uint32_t myId = 0; uint32_t myId = 0;
uint32_t remoteId = 0; uint32_t remoteId = 0;
uint8_t authSeq = 0x00; uint16_t authSeq = 0x30;
uint16_t sendSeqB = 0; uint16_t sendSeqB = 0;
uint16_t sendSeq = 1; uint16_t sendSeq = 1;
uint16_t lastReceivedSeq = 1; uint16_t lastReceivedSeq = 1;

Wyświetl plik

@ -4,10 +4,8 @@
#define STALE_CONNECTION 15 #define STALE_CONNECTION 15
#define LOCK_PERIOD 10 // time to attempt to lock Mutex in ms #define LOCK_PERIOD 10 // time to attempt to lock Mutex in ms
#define AUDIO_SEND_PERIOD 20 // #define AUDIO_SEND_PERIOD 20 //
udpServer::udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAudio) : udpServer::udpServer(SERVERCONFIG* config) :
config(config), config(config)
outAudio(outAudio),
inAudio(inAudio)
{ {
qInfo(logUdpServer()) << "Starting udp server"; qInfo(logUdpServer()) << "Starting udp server";
} }
@ -15,7 +13,7 @@ udpServer::udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAud
void udpServer::init() void udpServer::init()
{ {
for (RIGCONFIG* rig : config.rigs) for (RIGCONFIG* rig : config->rigs)
{ {
qDebug(logUdpServer()) << "CIV:" << rig->civAddr; qDebug(logUdpServer()) << "CIV:" << rig->civAddr;
qDebug(logUdpServer()) << "Model:" << rig->modelName; qDebug(logUdpServer()) << "Model:" << rig->modelName;
@ -53,36 +51,40 @@ void udpServer::init()
} }
} }
QString macTemp;
foreach(QNetworkInterface netInterface, QNetworkInterface::allInterfaces()) foreach(QNetworkInterface netInterface, QNetworkInterface::allInterfaces())
{ {
// Return only the first non-loopback MAC Address // Return only the first non-loopback MAC Address
if (!(netInterface.flags() & QNetworkInterface::IsLoopBack)) { if (!(netInterface.flags() & QNetworkInterface::IsLoopBack)) {
macAddress = netInterface.hardwareAddress(); macTemp = netInterface.hardwareAddress();
} }
} }
memcpy(&macAddress, macTemp.toLocal8Bit(), 6);
memcpy(&macAddress, QByteArrayLiteral("\x00\x90\xc7").constData(), 3);
uint32_t addr = localIP.toIPv4Address(); uint32_t addr = localIP.toIPv4Address();
qInfo(logUdpServer()) << "My IP Address:" << QHostAddress(addr).toString() << "My MAC Address:" << macAddress; qInfo(logUdpServer()) << "My IP Address:" << QHostAddress(addr).toString();
controlId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.controlPort & 0xffff); controlId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->controlPort & 0xffff);
civId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.civPort & 0xffff); civId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->civPort & 0xffff);
audioId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.audioPort & 0xffff); audioId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->audioPort & 0xffff);
qInfo(logUdpServer()) << "Server Binding Control to: " << config.controlPort; qInfo(logUdpServer()) << "Server Binding Control to: " << config->controlPort;
udpControl = new QUdpSocket(this); udpControl = new QUdpSocket(this);
udpControl->bind(config.controlPort); udpControl->bind(config->controlPort);
QUdpSocket::connect(udpControl, &QUdpSocket::readyRead, this, &udpServer::controlReceived); QUdpSocket::connect(udpControl, &QUdpSocket::readyRead, this, &udpServer::controlReceived);
qInfo(logUdpServer()) << "Server Binding CIV to: " << config.civPort; qInfo(logUdpServer()) << "Server Binding CIV to: " << config->civPort;
udpCiv = new QUdpSocket(this); udpCiv = new QUdpSocket(this);
udpCiv->bind(config.civPort); udpCiv->bind(config->civPort);
QUdpSocket::connect(udpCiv, &QUdpSocket::readyRead, this, &udpServer::civReceived); QUdpSocket::connect(udpCiv, &QUdpSocket::readyRead, this, &udpServer::civReceived);
qInfo(logUdpServer()) << "Server Binding Audio to: " << config.audioPort; qInfo(logUdpServer()) << "Server Binding Audio to: " << config->audioPort;
udpAudio = new QUdpSocket(this); udpAudio = new QUdpSocket(this);
udpAudio->bind(config.audioPort); udpAudio->bind(config->audioPort);
QUdpSocket::connect(udpAudio, &QUdpSocket::readyRead, this, &udpServer::audioReceived); QUdpSocket::connect(udpAudio, &QUdpSocket::readyRead, this, &udpServer::audioReceived);
wdTimer = new QTimer(); wdTimer = new QTimer();
@ -129,8 +131,8 @@ udpServer::~udpServer()
void udpServer::receiveRigCaps(rigCapabilities caps) void udpServer::receiveRigCaps(rigCapabilities caps)
{ {
for (RIGCONFIG* rig: config.rigs) { for (RIGCONFIG* rig: config->rigs) {
if (!memcmp(rig->guid, caps.guid, GUIDLEN)) { if (!memcmp(rig->guid, caps.guid, GUIDLEN) || config->rigs.size()==1) {
// Matching rig, fill-in missing details // Matching rig, fill-in missing details
rig->rigAvailable = true; rig->rigAvailable = true;
rig->modelName = caps.modelName; rig->modelName = caps.modelName;
@ -173,8 +175,8 @@ void udpServer::controlReceived()
current->timeConnected = QDateTime::currentDateTime(); current->timeConnected = QDateTime::currentDateTime();
current->ipAddress = datagram.senderAddress(); current->ipAddress = datagram.senderAddress();
current->port = datagram.senderPort(); current->port = datagram.senderPort();
current->civPort = config.civPort; current->civPort = config->civPort;
current->audioPort = config.audioPort; current->audioPort = config->audioPort;
current->myId = controlId; current->myId = controlId;
current->remoteId = qFromLittleEndian<quint32>(r.mid(8, 4)); current->remoteId = qFromLittleEndian<quint32>(r.mid(8, 4));
current->socket = udpControl; current->socket = udpControl;
@ -194,8 +196,16 @@ void udpServer::controlReceived()
qInfo(logUdpServer()) << current->ipAddress.toString() << ": New Control connection created"; qInfo(logUdpServer()) << current->ipAddress.toString() << ": New Control connection created";
if (connMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD))) if (connMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD)))
{ {
// Quick hack to replace the GUID with a MAC address.
if (config->rigs.size() == 1) {
memset(config->rigs.first()->guid, 0, GUIDLEN);
config->rigs.first()->commoncap = (quint16)0x8010;
memcpy(config->rigs.first()->macaddress, macAddress, 6);
memcpy(current->guid, config->rigs.first()->guid, GUIDLEN);
}
controlClients.append(current); controlClients.append(current);
connMutex.unlock(); connMutex.unlock();
} }
@ -255,26 +265,26 @@ void udpServer::controlReceived()
token_packet_t in = (token_packet_t)r.constData(); token_packet_t in = (token_packet_t)r.constData();
current->rxSeq = in->seq; current->rxSeq = in->seq;
current->authInnerSeq = in->innerseq; current->authInnerSeq = in->innerseq;
memcpy(current->macaddress, in->macaddress, 6); memcpy(current->guid, in->guid, GUIDLEN);
if (in->res == 0x02) { if (in->requesttype == 0x02 && in->requestreply == 0x01) {
// Request for new token // Request for new token
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received create token request"; qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received create token request";
sendCapabilities(current); sendCapabilities(current);
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
sendConnectionInfo(current, radio->guid); sendConnectionInfo(current, radio->guid);
} }
} }
else if (in->res == 0x01) { else if (in->requesttype == 0x01 && in->requestreply == 0x01) {
// Token disconnect // Token disconnect
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token disconnect request"; qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token disconnect request";
sendTokenResponse(current, in->res); sendTokenResponse(current, in->requesttype);
} }
else if (in->res == 0x04) { else if (in->requesttype == 0x04 && in->requestreply == 0x01) {
// Disconnect audio/civ // Disconnect audio/civ
sendTokenResponse(current, in->res); sendTokenResponse(current, in->requesttype);
current->isStreaming = false; current->isStreaming = false;
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
if (!memcmp(radio->guid, current->guid, GUIDLEN)) if (!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size() == 1)
{ {
sendConnectionInfo(current, radio->guid); sendConnectionInfo(current, radio->guid);
} }
@ -282,7 +292,7 @@ void udpServer::controlReceived()
} }
else { else {
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token request"; qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token request";
sendTokenResponse(current, in->res); sendTokenResponse(current, in->requesttype);
} }
break; break;
} }
@ -290,7 +300,7 @@ void udpServer::controlReceived()
{ {
login_packet_t in = (login_packet_t)r.constData(); login_packet_t in = (login_packet_t)r.constData();
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received 'login'"; qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received 'login'";
foreach(SERVERUSER user, config.users) foreach(SERVERUSER user, config->users)
{ {
QByteArray usercomp; QByteArray usercomp;
passcode(user.username, usercomp); passcode(user.username, usercomp);
@ -345,9 +355,9 @@ void udpServer::controlReceived()
audioSetup setup; audioSetup setup;
setup.resampleQuality = config.resampleQuality; setup.resampleQuality = config->resampleQuality;
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->txaudio == Q_NULLPTR) if ((!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size()==1) && radio->txaudio == Q_NULLPTR )
{ {
radio->txAudioSetup.codec = current->txCodec; radio->txAudioSetup.codec = current->txCodec;
radio->txAudioSetup.format.setSampleRate(current->txSampleRate); radio->txAudioSetup.format.setSampleRate(current->txSampleRate);
@ -380,7 +390,7 @@ void udpServer::controlReceived()
connect(this, SIGNAL(haveAudioData(audioPacket)), radio->txaudio, SLOT(incomingAudio(audioPacket))); connect(this, SIGNAL(haveAudioData(audioPacket)), radio->txaudio, SLOT(incomingAudio(audioPacket)));
} }
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->rxaudio == Q_NULLPTR) if ((!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size() == 1) && radio->rxaudio == Q_NULLPTR)
{ {
#if !defined(PORTAUDIO) && !defined(RTAUDIO) #if !defined(PORTAUDIO) && !defined(RTAUDIO)
qInfo(logUdpServer()) << "Radio" << radio->rigName << "audio input(RX) :" << radio->rxAudioSetup.port.deviceName(); qInfo(logUdpServer()) << "Radio" << radio->rigName << "audio input(RX) :" << radio->rxAudioSetup.port.deviceName();
@ -404,7 +414,6 @@ void udpServer::controlReceived()
radio->rxAudioThread->start(QThread::TimeCriticalPriority); radio->rxAudioThread->start(QThread::TimeCriticalPriority);
connect(this, SIGNAL(setupRxAudio(audioSetup)), radio->rxaudio, SLOT(init(audioSetup)));
connect(radio->rxAudioThread, SIGNAL(finished()), radio->rxaudio, SLOT(deleteLater())); connect(radio->rxAudioThread, SIGNAL(finished()), radio->rxaudio, SLOT(deleteLater()));
connect(radio->rxaudio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket))); connect(radio->rxaudio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
@ -414,6 +423,7 @@ void udpServer::controlReceived()
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
#else #else
#warning "QT 5.9 is not fully supported multiple rigs will NOT work!" #warning "QT 5.9 is not fully supported multiple rigs will NOT work!"
connect(this, SIGNAL(setupRxAudio(audioSetup)), radio->rxaudio, SLOT(init(audioSetup)));
setupRxAudio(radio->rxAudioSetup); setupRxAudio(radio->rxAudioSetup);
#endif #endif
@ -573,10 +583,11 @@ void udpServer::civReceived()
qDebug(logUdpServer()) << current->ipAddress.toString() << ": Detected invalid remote CI-V:" << hex << (quint8)r[lastFE+2]; qDebug(logUdpServer()) << current->ipAddress.toString() << ": Detected invalid remote CI-V:" << hex << (quint8)r[lastFE+2];
} }
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
if (!memcmp(radio->guid, current->guid, sizeof(radio->guid))) if (!memcmp(radio->guid, current->guid, sizeof(radio->guid)) || config->rigs.size()==1)
{ {
// Only send to the rig that it belongs to! // Only send to the rig that it belongs to!
//qDebug(logUdpServer()) << "Sending data" << r.mid(0x15);
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0)) #if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
QMetaObject::invokeMethod(radio->rig, [=]() { QMetaObject::invokeMethod(radio->rig, [=]() {
radio->rig->dataFromServer(r.mid(0x15));; radio->rig->dataFromServer(r.mid(0x15));;
@ -1095,7 +1106,9 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
p.innerseq = c->authInnerSeq; p.innerseq = c->authInnerSeq;
p.tokrequest = c->tokenRx; p.tokrequest = c->tokenRx;
p.token = c->tokenTx; p.token = c->tokenTx;
p.code = 0x0250; p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.requesttype = 0x00;
p.requestreply = 0x01;
if (!allowed) { if (!allowed) {
@ -1108,7 +1121,8 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
c->retransmitTimer->stop(); c->retransmitTimer->stop();
} }
else { else {
strcpy(p.connection, "WFVIEW"); //strcpy(p.connection, "WFVIEW");
strcpy(p.connection, "FTTH");
} }
SEQBUFENTRY s; SEQBUFENTRY s;
@ -1157,20 +1171,21 @@ void udpServer::sendCapabilities(CLIENT* c)
p.innerseq = c->authInnerSeq; p.innerseq = c->authInnerSeq;
p.tokrequest = c->tokenRx; p.tokrequest = c->tokenRx;
p.token = c->tokenTx; p.token = c->tokenTx;
p.res = 0x0202; p.requesttype = 0x02;
p.numradios = config.rigs.count(); p.requestreply = 0x02;
p.numradios = qToBigEndian((quint16)config->rigs.size());
SEQBUFENTRY s; SEQBUFENTRY s;
s.seqNum = p.seq; s.seqNum = p.seq;
s.timeSent = QTime::currentTime(); s.timeSent = QTime::currentTime();
s.retransmitCount = 0; s.retransmitCount = 0;
for (RIGCONFIG* rig : config.rigs) { for (RIGCONFIG* rig : config->rigs) {
qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending Capabilities :" << c->txSeq << "for" << rig->modelName; qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending Capabilities :" << c->txSeq << "for" << rig->modelName;
radio_cap_packet r; radio_cap_packet r;
memset(r.packet, 0x0, sizeof(r)); // We can't be sure it is initialized with 0x00! memset(r.packet, 0x0, sizeof(r)); // We can't be sure it is initialized with 0x00!
memcpy(r.guid, rig->guid, GUIDLEN); memcpy(r.guid, rig->guid, GUIDLEN);
memcpy(r.name, rig->rigName.toLocal8Bit(), sizeof(r.name)); memcpy(r.name, rig->rigName.toLocal8Bit(), sizeof(r.name));
memcpy(r.audio, QByteArrayLiteral("ICOM_VAUDIO").constData(), 11); memcpy(r.audio, QByteArrayLiteral("ICOM_VAUDIO").constData(), 11);
@ -1233,7 +1248,7 @@ void udpServer::sendCapabilities(CLIENT* c)
} }
p.len = sizeof(p)+s.data.length(); p.len = sizeof(p)+s.data.length();
p.payloadsize = sizeof(p)+s.data.length() - 0x0f; p.payloadsize = qToBigEndian((quint16)(sizeof(p) + s.data.length() - 0x10));
s.data.insert(0,QByteArray::fromRawData((const char*)p.packet, sizeof(p))); s.data.insert(0,QByteArray::fromRawData((const char*)p.packet, sizeof(p)));
@ -1271,8 +1286,8 @@ void udpServer::sendCapabilities(CLIENT* c)
// Also used to display currently connected used information. // Also used to display currently connected used information.
void udpServer::sendConnectionInfo(CLIENT* c, quint8 guid[GUIDLEN]) void udpServer::sendConnectionInfo(CLIENT* c, quint8 guid[GUIDLEN])
{ {
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
if (!memcmp(guid, radio->guid, GUIDLEN)) if (!memcmp(guid, radio->guid, GUIDLEN) || config->rigs.size()==1)
{ {
qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending ConnectionInfo :" << c->txSeq; qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending ConnectionInfo :" << c->txSeq;
conninfo_packet p; conninfo_packet p;
@ -1285,7 +1300,10 @@ void udpServer::sendConnectionInfo(CLIENT* c, quint8 guid[GUIDLEN])
//p.innerseq = c->authInnerSeq; // Innerseq not used in user packet //p.innerseq = c->authInnerSeq; // Innerseq not used in user packet
p.tokrequest = c->tokenRx; p.tokrequest = c->tokenRx;
p.token = c->tokenTx; p.token = c->tokenTx;
p.code = 0x0380; p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.requesttype = 0x00;
p.requestreply = 0x03;
memcpy(p.guid, radio->guid, GUIDLEN); memcpy(p.guid, radio->guid, GUIDLEN);
memcpy(p.name, radio->rigName.toLocal8Bit(), sizeof(p.name)); memcpy(p.name, radio->rigName.toLocal8Bit(), sizeof(p.name));
@ -1362,11 +1380,11 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
p.innerseq = c->authInnerSeq; p.innerseq = c->authInnerSeq;
p.tokrequest = c->tokenRx; p.tokrequest = c->tokenRx;
p.token = c->tokenTx; p.token = c->tokenTx;
p.code = 0x0230; p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
memcpy(p.macaddress, c->macaddress, 6);
p.commoncap = c->commonCap;
p.res = type;
memcpy(p.guid, c->guid, GUIDLEN);
p.requesttype = type;
p.requestreply = 0x02;
SEQBUFENTRY s; SEQBUFENTRY s;
s.seqNum = p.seq; s.seqNum = p.seq;
@ -1473,11 +1491,10 @@ void udpServer::sendStatus(CLIENT* c)
p.innerseq = c->authInnerSeq; p.innerseq = c->authInnerSeq;
p.tokrequest = c->tokenRx; p.tokrequest = c->tokenRx;
p.token = c->tokenTx; p.token = c->tokenTx;
p.code = 0x0240; p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
p.res = 0x03; p.requestreply = 0x02;
p.unknown = 0x1000; p.requesttype = 0x03;
p.unusede = (char)0x80; memcpy(p.guid, c->guid, GUIDLEN); // May be MAC address OR guid.
memcpy(p.macaddress, c->macaddress, 6);
p.civport = qToBigEndian(c->civPort); p.civport = qToBigEndian(c->civPort);
@ -1534,7 +1551,7 @@ void udpServer::dataForServer(QByteArray d)
continue; continue;
} }
// Use the GUID to determine which radio the response is from // Use the GUID to determine which radio the response is from
if (memcmp(sender->getGUID(), client->guid, GUIDLEN)) if (memcmp(sender->getGUID(), client->guid, GUIDLEN) && config->rigs.size()>1)
{ {
continue; // Rig guid doesn't match the one requested by the client. continue; // Rig guid doesn't match the one requested by the client.
} }
@ -1571,7 +1588,7 @@ void udpServer::dataForServer(QByteArray d)
} }
client->txSeqBuf.insert(p.seq, s); client->txSeqBuf.insert(p.seq, s);
client->txSeq++; client->txSeq++;
client->innerSeq++; //client->innerSeq = (qToBigEndian(qFromBigEndian(client->innerSeq) + 1));
client->txMutex.unlock(); client->txMutex.unlock();
} }
else { else {
@ -1607,7 +1624,7 @@ void udpServer::receiveAudioData(const audioPacket& d)
else { else {
memcpy(guid, d.guid, GUIDLEN); memcpy(guid, d.guid, GUIDLEN);
} }
//qInfo(logUdpServer()) << "Server got:" << d.data.length(); //qInfo(logUdpServer()) << "Server got:" << d.data.length();
foreach(CLIENT * client, audioClients) foreach(CLIENT * client, audioClients)
{ {
int len = 0; int len = 0;
@ -1615,7 +1632,7 @@ void udpServer::receiveAudioData(const audioPacket& d)
QByteArray partial; QByteArray partial;
partial = d.data.mid(len, 1364); partial = d.data.mid(len, 1364);
len = len + partial.length(); len = len + partial.length();
if (client != Q_NULLPTR && client->connected && !memcmp(client->guid, guid, GUIDLEN)) { if (client != Q_NULLPTR && client->connected && (!memcmp(client->guid, guid, GUIDLEN) || config->rigs.size()== 1)) {
audio_packet p; audio_packet p;
memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00! memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00!
p.len = sizeof(p) + partial.length(); p.len = sizeof(p) + partial.length();
@ -1698,19 +1715,22 @@ void udpServer::sendRetransmitRequest(CLIENT* c)
{ {
for (auto it = c->rxMissing.begin(); it != c->rxMissing.end(); ++it) for (auto it = c->rxMissing.begin(); it != c->rxMissing.end(); ++it)
{ {
if (&it.key() != Q_NULLPTR && it.value() < 4) if (&it.key() != Q_NULLPTR)
{ {
missingSeqs.append(it.key() & 0xff); if (it.value() < 4)
missingSeqs.append(it.key() >> 8 & 0xff); {
missingSeqs.append(it.key() & 0xff); missingSeqs.append(it.key() & 0xff);
missingSeqs.append(it.key() >> 8 & 0xff); missingSeqs.append(it.key() >> 8 & 0xff);
it.value()++; missingSeqs.append(it.key() & 0xff);
} missingSeqs.append(it.key() >> 8 & 0xff);
it.value()++;
}
else { else {
// We have tried 4 times to request this packet, time to give up! // We have tried 4 times to request this packet, time to give up!
qDebug(logUdp()) << this->metaObject()->className() << ": No response for missing packet" << it.key() << "deleting"; qDebug(logUdp()) << this->metaObject()->className() << ": No response for missing packet" << it.key() << "deleting";
it = c->rxMissing.erase(it); it = c->rxMissing.erase(it);
}
} }
} }
@ -1844,8 +1864,8 @@ void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
} }
if (len == 0) { if (len == 0) {
for (RIGCONFIG* radio : config.rigs) { for (RIGCONFIG* radio : config->rigs) {
if (!memcmp(radio->guid, guid, GUIDLEN)) if (!memcmp(radio->guid, guid, GUIDLEN) || config->rigs.size() == 1)
{ {
if (radio->rxAudioThread != Q_NULLPTR) { if (radio->rxAudioThread != Q_NULLPTR) {

Wyświetl plik

@ -42,6 +42,7 @@ struct SERVERUSER {
quint8 userType; quint8 userType;
}; };
struct RIGCONFIG { struct RIGCONFIG {
QString serialPort; QString serialPort;
quint32 baudRate; quint32 baudRate;
@ -54,7 +55,17 @@ struct RIGCONFIG {
audioSetup txAudioSetup; audioSetup txAudioSetup;
QString modelName; QString modelName;
QString rigName; QString rigName;
quint8 guid[GUIDLEN]; #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; bool rigAvailable=false;
rigCapabilities rigCaps; rigCapabilities rigCaps;
rigCommander* rig = Q_NULLPTR; rigCommander* rig = Q_NULLPTR;
@ -88,7 +99,7 @@ class udpServer : public QObject
Q_OBJECT Q_OBJECT
public: public:
udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAudio); udpServer(SERVERCONFIG* config);
~udpServer(); ~udpServer();
public slots: public slots:
@ -128,11 +139,11 @@ private:
quint16 connSeq; quint16 connSeq;
quint16 pingSeq; quint16 pingSeq;
quint32 rxPingTime; // 32bit as has other info quint32 rxPingTime; // 32bit as has other info
quint8 authInnerSeq; quint16 authInnerSeq;
quint16 authSeq; quint16 authSeq;
quint16 innerSeq; quint16 innerSeq;
quint16 sendAudioSeq; quint16 sendAudioSeq;
quint8 macaddress[4]; quint8 macaddress[6];
quint16 tokenRx; quint16 tokenRx;
quint32 tokenTx; quint32 tokenTx;
quint32 commonCap; quint32 commonCap;
@ -186,13 +197,13 @@ private:
void watchdog(); void watchdog();
void deleteConnection(QList<CLIENT*> *l, CLIENT* c); void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
SERVERCONFIG config; SERVERCONFIG *config;
QUdpSocket* udpControl = Q_NULLPTR; QUdpSocket* udpControl = Q_NULLPTR;
QUdpSocket* udpCiv = Q_NULLPTR; QUdpSocket* udpCiv = Q_NULLPTR;
QUdpSocket* udpAudio = Q_NULLPTR; QUdpSocket* udpAudio = Q_NULLPTR;
QHostAddress localIP; QHostAddress localIP;
QString macAddress; quint8 macAddress[6];
quint32 controlId = 0; quint32 controlId = 0;
quint32 civId = 0; quint32 civId = 0;

Wyświetl plik

@ -111,10 +111,6 @@ wfmain::~wfmain()
delete ui; delete ui;
delete settings; delete settings;
#if defined(PORTAUDIO)
Pa_Terminate();
#endif
} }
void wfmain::closeEvent(QCloseEvent *event) void wfmain::closeEvent(QCloseEvent *event)
@ -999,9 +995,9 @@ void wfmain::setServerToPrefs()
if (serverConfig.enabled) { if (serverConfig.enabled) {
serverConfig.lan = prefs.enableLAN; serverConfig.lan = prefs.enableLAN;
qInfo(logAudio()) << "Audio Input device " << serverRxSetup.name; qInfo(logAudio()) << "Audio Input device " << serverConfig.rigs.first()->rxAudioSetup.name;
qInfo(logAudio()) << "Audio Output device " << serverTxSetup.name; qInfo(logAudio()) << "Audio Output device " << serverConfig.rigs.first()->txAudioSetup.name;
udp = new udpServer(serverConfig, serverTxSetup, serverRxSetup); udp = new udpServer(&serverConfig);
serverThread = new QThread(this); serverThread = new QThread(this);
@ -1067,100 +1063,8 @@ void wfmain::setUIToPrefs()
void wfmain::setAudioDevicesUI() void wfmain::setAudioDevicesUI()
{ {
#if defined(RTAUDIO)
#if defined(Q_OS_LINUX)
RtAudio* audio = new RtAudio(RtAudio::Api::LINUX_ALSA);
#elif defined(Q_OS_WIN)
RtAudio* audio = new RtAudio(RtAudio::Api::WINDOWS_WASAPI);
#elif defined(Q_OS_MACX)
RtAudio* audio = new RtAudio(RtAudio::Api::MACOSX_CORE);
#endif
// Enumerate audio devices, need to do before settings are loaded. // Enumerate audio devices, need to do before settings are loaded.
std::map<int, std::string> apiMap; qDebug(logSystem()) << "Finding audio output devices";
apiMap[RtAudio::MACOSX_CORE] = "OS-X Core Audio";
apiMap[RtAudio::WINDOWS_ASIO] = "Windows ASIO";
apiMap[RtAudio::WINDOWS_DS] = "Windows DirectSound";
apiMap[RtAudio::WINDOWS_WASAPI] = "Windows WASAPI";
apiMap[RtAudio::UNIX_JACK] = "Jack Client";
apiMap[RtAudio::LINUX_ALSA] = "Linux ALSA";
apiMap[RtAudio::LINUX_PULSE] = "Linux PulseAudio";
apiMap[RtAudio::LINUX_OSS] = "Linux OSS";
apiMap[RtAudio::RTAUDIO_DUMMY] = "RtAudio Dummy";
std::vector< RtAudio::Api > apis;
RtAudio::getCompiledApi(apis);
qInfo(logAudio()) << "RtAudio Version " << QString::fromStdString(RtAudio::getVersion());
qInfo(logAudio()) << "Compiled APIs:";
for (unsigned int i = 0; i < apis.size(); i++) {
qInfo(logAudio()) << " " << QString::fromStdString(apiMap[apis[i]]);
}
RtAudio::DeviceInfo info;
qInfo(logAudio()) << "Current API: " << QString::fromStdString(apiMap[audio->getCurrentApi()]);
unsigned int devices = audio->getDeviceCount();
qInfo(logAudio()) << "Found " << devices << " audio device(s) *=default";
for (unsigned int i = 1; i < devices; i++) {
info = audio->getDeviceInfo(i);
if (info.outputChannels > 0) {
qInfo(logAudio()) << (info.isDefaultOutput ? "*" : " ") << "(" << i << ") Output Device : " << QString::fromStdString(info.name);
ui->audioOutputCombo->addItem(QString::fromStdString(info.name), i);
ui->serverTXAudioOutputCombo->addItem(QString::fromStdString(info.name), i);
}
if (info.inputChannels > 0) {
qInfo(logAudio()) << (info.isDefaultInput ? "*" : " ") << "(" << i << ") Input Device : " << QString::fromStdString(info.name);
ui->audioInputCombo->addItem(QString::fromStdString(info.name), i);
ui->serverRXAudioInputCombo->addItem(QString::fromStdString(info.name), i);
}
}
delete audio;
#elif defined(PORTAUDIO)
// Use PortAudio device enumeration
PaError err;
err = Pa_Initialize();
if (err != paNoError)
{
qInfo(logAudio()) << "ERROR: Cannot initialize Portaudio";
}
qInfo(logAudio()) << "PortAudio version: " << Pa_GetVersionInfo()->versionText;
int numDevices;
numDevices = Pa_GetDeviceCount();
qInfo(logAudio()) << "Pa_CountDevices returned" << numDevices;
const PaDeviceInfo* info;
for (int i = 0; i < numDevices; i++)
{
info = Pa_GetDeviceInfo(i);
if (info->maxInputChannels > 0) {
qInfo(logAudio()) << (i == Pa_GetDefaultInputDevice() ? "*" : " ") << "(" << i << ") Output Device : " << info->name;
ui->audioInputCombo->addItem(info->name, i);
ui->serverRXAudioInputCombo->addItem(info->name, i);
}
if (info->maxOutputChannels > 0) {
qInfo(logAudio()) << (i == Pa_GetDefaultOutputDevice() ? "*" : " ") << "(" << i << ") Input Device : " << info->name;
ui->audioOutputCombo->addItem(info->name, i);
ui->serverTXAudioOutputCombo->addItem(info->name, i);
}
}
#else
// If no external library is configured, use QTMultimedia
// Enumerate audio devices, need to do before settings are loaded.
qDebug(logSystem()) << "Finding audio input devices";
const auto audioOutputs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); const auto audioOutputs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
for (const QAudioDeviceInfo& deviceInfo : audioOutputs) { for (const QAudioDeviceInfo& deviceInfo : audioOutputs) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -1174,7 +1078,7 @@ void wfmain::setAudioDevicesUI()
#endif #endif
} }
qDebug(logSystem()) << "Finding audio output devices"; qDebug(logSystem()) << "Finding audio input devices";
const auto audioInputs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); const auto audioInputs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
for (const QAudioDeviceInfo& deviceInfo : audioInputs) { for (const QAudioDeviceInfo& deviceInfo : audioInputs) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -1190,10 +1094,7 @@ void wfmain::setAudioDevicesUI()
qDebug(logSystem()) << "Audio devices done."; qDebug(logSystem()) << "Audio devices done.";
rxSetup.port = QAudioDeviceInfo::defaultOutputDevice(); rxSetup.port = QAudioDeviceInfo::defaultOutputDevice();
txSetup.port = QAudioDeviceInfo::defaultInputDevice(); txSetup.port = QAudioDeviceInfo::defaultInputDevice();
serverRxSetup.port = txSetup.port;
serverTxSetup.port = rxSetup.port;
qDebug(logSystem()) << "Audio set to default device initially"; qDebug(logSystem()) << "Audio set to default device initially";
#endif
} }
void wfmain::setSerialDevicesUI() void wfmain::setSerialDevicesUI()
@ -1637,14 +1538,10 @@ void wfmain::loadSettings()
int audioOutputIndex = ui->audioOutputCombo->findText(rxSetup.name); int audioOutputIndex = ui->audioOutputCombo->findText(rxSetup.name);
if (audioOutputIndex != -1) { if (audioOutputIndex != -1) {
ui->audioOutputCombo->setCurrentIndex(audioOutputIndex); ui->audioOutputCombo->setCurrentIndex(audioOutputIndex);
#if defined(RTAUDIO)
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
#elif defined(PORTAUDIO)
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
#else
QVariant v = ui->audioOutputCombo->currentData(); QVariant v = ui->audioOutputCombo->currentData();
rxSetup.port = v.value<QAudioDeviceInfo>(); rxSetup.port = v.value<QAudioDeviceInfo>();
#endif
} }
ui->audioOutputCombo->blockSignals(false); ui->audioOutputCombo->blockSignals(false);
@ -1654,14 +1551,10 @@ void wfmain::loadSettings()
int audioInputIndex = ui->audioInputCombo->findText(txSetup.name); int audioInputIndex = ui->audioInputCombo->findText(txSetup.name);
if (audioInputIndex != -1) { if (audioInputIndex != -1) {
ui->audioInputCombo->setCurrentIndex(audioInputIndex); ui->audioInputCombo->setCurrentIndex(audioInputIndex);
#if defined(RTAUDIO)
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
#elif defined(PORTAUDIO)
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
#else
QVariant v = ui->audioInputCombo->currentData(); QVariant v = ui->audioInputCombo->currentData();
txSetup.port = v.value<QAudioDeviceInfo>(); txSetup.port = v.value<QAudioDeviceInfo>();
#endif
} }
ui->audioInputCombo->blockSignals(false); ui->audioInputCombo->blockSignals(false);
@ -1717,7 +1610,7 @@ void wfmain::loadSettings()
RIGCONFIG* rigTemp = new RIGCONFIG(); RIGCONFIG* rigTemp = new RIGCONFIG();
rigTemp->rxAudioSetup.isinput = true; rigTemp->rxAudioSetup.isinput = true;
rigTemp->txAudioSetup.isinput = true; rigTemp->txAudioSetup.isinput = false;
rigTemp->rxAudioSetup.localAFgain = 255; rigTemp->rxAudioSetup.localAFgain = 255;
rigTemp->txAudioSetup.localAFgain = 255; rigTemp->txAudioSetup.localAFgain = 255;
rigTemp->rxAudioSetup.resampleQuality = 4; rigTemp->rxAudioSetup.resampleQuality = 4;
@ -1742,14 +1635,10 @@ void wfmain::loadSettings()
int serverAudioInputIndex = ui->serverRXAudioInputCombo->findText(rigTemp->rxAudioSetup.name); int serverAudioInputIndex = ui->serverRXAudioInputCombo->findText(rigTemp->rxAudioSetup.name);
if (serverAudioInputIndex != -1) { if (serverAudioInputIndex != -1) {
ui->serverRXAudioInputCombo->setCurrentIndex(serverAudioInputIndex); ui->serverRXAudioInputCombo->setCurrentIndex(serverAudioInputIndex);
#if defined(RTAUDIO)
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(serverAudioInputIndex).toInt();
#elif defined(PORTAUDIO)
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(serverAudioInputIndex).toInt();
#else
QVariant v = ui->serverRXAudioInputCombo->currentData(); QVariant v = ui->serverRXAudioInputCombo->currentData();
rigTemp->rxAudioSetup.port = v.value<QAudioDeviceInfo>(); rigTemp->rxAudioSetup.port = v.value<QAudioDeviceInfo>();
#endif
} }
ui->serverRXAudioInputCombo->blockSignals(false); ui->serverRXAudioInputCombo->blockSignals(false);
@ -1759,17 +1648,12 @@ void wfmain::loadSettings()
int serverAudioOutputIndex = ui->serverTXAudioOutputCombo->findText(rigTemp->txAudioSetup.name); int serverAudioOutputIndex = ui->serverTXAudioOutputCombo->findText(rigTemp->txAudioSetup.name);
if (serverAudioOutputIndex != -1) { if (serverAudioOutputIndex != -1) {
ui->serverTXAudioOutputCombo->setCurrentIndex(serverAudioOutputIndex); ui->serverTXAudioOutputCombo->setCurrentIndex(serverAudioOutputIndex);
#if defined(RTAUDIO)
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(serverAudioOutputIndex).toInt();
#elif defined(PORTAUDIO)
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(serverAudioOutputIndex).toInt();
#else
QVariant v = ui->serverTXAudioOutputCombo->currentData(); QVariant v = ui->serverTXAudioOutputCombo->currentData();
rigTemp->txAudioSetup.port = v.value<QAudioDeviceInfo>(); rigTemp->txAudioSetup.port = v.value<QAudioDeviceInfo>();
#endif
} }
ui->serverTXAudioOutputCombo->blockSignals(false); ui->serverTXAudioOutputCombo->blockSignals(false);
serverConfig.rigs.append(rigTemp); serverConfig.rigs.append(rigTemp);
int row = 0; int row = 0;
@ -1910,30 +1794,25 @@ void wfmain::on_serverAudioPortText_textChanged(QString text)
void wfmain::on_serverRXAudioInputCombo_currentIndexChanged(int value) void wfmain::on_serverRXAudioInputCombo_currentIndexChanged(int value)
{ {
#if defined(RTAUDIO) if (serverConfig.rigs.size() > 0)
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(value).toInt(); {
#elif defined(PORTAUDIO) QVariant v = ui->serverRXAudioInputCombo->itemData(value);
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(value).toInt(); serverConfig.rigs.first()->rxAudioSetup.port = v.value<QAudioDeviceInfo>();
#else
QVariant v = ui->serverRXAudioInputCombo->itemData(value); serverConfig.rigs.first()->rxAudioSetup.name = ui->serverRXAudioInputCombo->itemText(value);
serverRxSetup.port = v.value<QAudioDeviceInfo>(); qDebug(logGui()) << "Changed default server audio input to:" << serverConfig.rigs.first()->rxAudioSetup.name;
#endif }
serverRxSetup.name = ui->serverRXAudioInputCombo->itemText(value);
qDebug(logGui()) << "Changed default server audio input to:" << serverRxSetup.name;
} }
void wfmain::on_serverTXAudioOutputCombo_currentIndexChanged(int value) void wfmain::on_serverTXAudioOutputCombo_currentIndexChanged(int value)
{ {
#if defined(RTAUDIO) if (serverConfig.rigs.size() > 0) {
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(value).toInt(); QVariant v = ui->serverTXAudioOutputCombo->itemData(value);
#elif defined(PORTAUDIO) serverConfig.rigs.first()->txAudioSetup.port = v.value<QAudioDeviceInfo>();
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(value).toInt();
#else serverConfig.rigs.first()->txAudioSetup.name = ui->serverTXAudioOutputCombo->itemText(value);
QVariant v = ui->serverTXAudioOutputCombo->itemData(value); qDebug(logGui()) << "Changed default server audio output to:" << serverConfig.rigs.first()->txAudioSetup.name;
serverTxSetup.port = v.value<QAudioDeviceInfo>(); }
#endif
serverTxSetup.name = ui->serverTXAudioOutputCombo->itemText(value);
qDebug(logGui()) << "Changed default server audio output to:" << serverTxSetup.name;
} }
void wfmain::on_serverUsersTable_cellChanged(int row, int column) void wfmain::on_serverUsersTable_cellChanged(int row, int column)
@ -2097,8 +1976,8 @@ void wfmain::saveSettings()
settings->setValue("ServerControlPort", serverConfig.controlPort); settings->setValue("ServerControlPort", serverConfig.controlPort);
settings->setValue("ServerCivPort", serverConfig.civPort); settings->setValue("ServerCivPort", serverConfig.civPort);
settings->setValue("ServerAudioPort", serverConfig.audioPort); settings->setValue("ServerAudioPort", serverConfig.audioPort);
settings->setValue("ServerAudioOutput", serverTxSetup.name); settings->setValue("ServerAudioOutput", serverConfig.rigs.first()->txAudioSetup.name);
settings->setValue("ServerAudioInput", serverRxSetup.name); settings->setValue("ServerAudioInput", serverConfig.rigs.first()->rxAudioSetup.name);
/* Remove old format users*/ /* Remove old format users*/
int numUsers = settings->value("ServerNumUsers", 0).toInt(); int numUsers = settings->value("ServerNumUsers", 0).toInt();
@ -3343,6 +3222,12 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
this->rigCaps = rigCaps; this->rigCaps = rigCaps;
rigName->setText(rigCaps.modelName); rigName->setText(rigCaps.modelName);
if (serverConfig.enabled) {
serverConfig.rigs.first()->modelName = rigCaps.modelName;
serverConfig.rigs.first()->rigName = rigCaps.modelName;
serverConfig.rigs.first()->civAddr = rigCaps.civ;
serverConfig.rigs.first()->baudRate = rigCaps.baudRate;
}
setWindowTitle(rigCaps.modelName); setWindowTitle(rigCaps.modelName);
this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true. this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true.
haveRigCaps = true; haveRigCaps = true;
@ -4734,28 +4619,18 @@ void wfmain::on_passwordTxt_textChanged(QString text)
void wfmain::on_audioOutputCombo_currentIndexChanged(int value) void wfmain::on_audioOutputCombo_currentIndexChanged(int value)
{ {
#if defined(RTAUDIO)
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
#elif defined(PORTAUDIO)
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
#else
QVariant v = ui->audioOutputCombo->itemData(value); QVariant v = ui->audioOutputCombo->itemData(value);
rxSetup.port = v.value<QAudioDeviceInfo>(); rxSetup.port = v.value<QAudioDeviceInfo>();
#endif
rxSetup.name = ui->audioOutputCombo->itemText(value); rxSetup.name = ui->audioOutputCombo->itemText(value);
qDebug(logGui()) << "Changed default audio output to:" << rxSetup.name; qDebug(logGui()) << "Changed default audio output to:" << rxSetup.name;
} }
void wfmain::on_audioInputCombo_currentIndexChanged(int value) void wfmain::on_audioInputCombo_currentIndexChanged(int value)
{ {
#if defined(RTAUDIO)
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
#elif defined(PORTAUDIO)
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
#else
QVariant v = ui->audioInputCombo->itemData(value); QVariant v = ui->audioInputCombo->itemData(value);
txSetup.port = v.value<QAudioDeviceInfo>(); txSetup.port = v.value<QAudioDeviceInfo>();
#endif
txSetup.name = ui->audioInputCombo->itemText(value); txSetup.name = ui->audioInputCombo->itemText(value);
qDebug(logGui()) << "Changed default audio input to:" << txSetup.name; qDebug(logGui()) << "Changed default audio input to:" << txSetup.name;
} }

Wyświetl plik

@ -780,8 +780,6 @@ private:
audioSetup rxSetup; audioSetup rxSetup;
audioSetup txSetup; audioSetup txSetup;
audioSetup serverRxSetup;
audioSetup serverTxSetup;
colors defaultColors; colors defaultColors;