Fixed double printing (... I think ...)
This commit is contained in:
parent
54a7085c47
commit
1ad0efa634
@ -19,7 +19,7 @@
|
|||||||
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
||||||
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
||||||
|
|
||||||
parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
|
parameter (AZ=12000.0/(1.0*NSPS)*0.8d0) !Dedupe overlap in Hz
|
||||||
parameter (ASTART=0.2) !Start delay in seconds
|
parameter (ASTART=0.2) !Start delay in seconds
|
||||||
parameter (ASYNCMIN=1.5) !Minimum Sync
|
parameter (ASYNCMIN=1.5) !Minimum Sync
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
||||||
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=20, NDD=90, JZ=62) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
||||||
|
|
||||||
parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
|
parameter (AZ=12000.0/(1.0*NSPS)*0.8d0) !Dedupe overlap in Hz
|
||||||
parameter (ASTART=0.1) !Start delay in seconds
|
parameter (ASTART=0.1) !Start delay in seconds
|
||||||
parameter (ASYNCMIN=1.5) !Minimum Sync
|
parameter (ASYNCMIN=1.5) !Minimum Sync
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
||||||
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=40, NDD=90, JZ=116) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
! parameter (NSPS=4000, NTXDUR=30, NDOWNSPS=40, NDD=90, JZ=116) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
||||||
|
|
||||||
parameter (AZ=12000.0/(1.0*NSPS)*0.64d0) !Dedupe overlap in Hz
|
parameter (AZ=12000.0/(1.0*NSPS)*0.8d0) !Dedupe overlap in Hz
|
||||||
parameter (ASTART=0.1) !Start delay in seconds
|
parameter (ASTART=0.1) !Start delay in seconds
|
||||||
parameter (ASYNCMIN=1.5) !Minimum Sync
|
parameter (ASYNCMIN=1.5) !Minimum Sync
|
||||||
|
|
||||||
|
@ -145,9 +145,13 @@ subroutine syncjs8(dd,nfa,nfb,syncmin,nfqso,s,candidate,ncand,sbase)
|
|||||||
enddo
|
enddo
|
||||||
ncand=k
|
ncand=k
|
||||||
|
|
||||||
! Put nfqso at top of list, and save only the best of near-dupe freqs.
|
! Put nfqso at top of list
|
||||||
do i=1,ncand
|
do i=1,ncand
|
||||||
if(abs(candidate0(1,i)-nfqso).lt.10.0) candidate0(1,i)=-candidate0(1,i)
|
if(abs(candidate0(1,i)-nfqso).lt.10.0) candidate0(1,i)=-candidate0(1,i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! Save only the best of near-dupe freqs.
|
||||||
|
do i=1,ncand
|
||||||
if(i.ge.2) then
|
if(i.ge.2) then
|
||||||
do j=1,i-1
|
do j=1,i-1
|
||||||
fdiff=abs(candidate0(1,i))-abs(candidate0(1,j))
|
fdiff=abs(candidate0(1,i))-abs(candidate0(1,j))
|
||||||
|
572
mainwindow.cpp
572
mainwindow.cpp
@ -4163,23 +4163,25 @@ QList<int> generateOffsets(int minOffset, int maxOffset){
|
|||||||
void MainWindow::readFromStdout() //readFromStdout
|
void MainWindow::readFromStdout() //readFromStdout
|
||||||
{
|
{
|
||||||
while(proc_js8.canReadLine()) {
|
while(proc_js8.canReadLine()) {
|
||||||
QByteArray t=proc_js8.readLine();
|
QByteArray t=proc_js8.readLine();
|
||||||
qDebug() << "JS8: " << QString(t);
|
qDebug() << "JS8: " << QString(t);
|
||||||
bool bAvgMsg=false;
|
bool bAvgMsg=false;
|
||||||
int navg=0;
|
int navg=0;
|
||||||
if(t.indexOf("<DecodeFinished>") >= 0) {
|
if(t.indexOf("<DecodeFinished>") >= 0) {
|
||||||
if(m_mode=="QRA64") m_wideGraph->drawRed(0,0);
|
if(m_mode=="QRA64") m_wideGraph->drawRed(0,0);
|
||||||
m_bDecoded = t.mid(20).trimmed().toInt() > 0;
|
m_bDecoded = t.mid(20).trimmed().toInt() > 0;
|
||||||
int mswait=3*1000*m_TRperiod/4;
|
int mswait=3*1000*m_TRperiod/4;
|
||||||
if(!m_diskData) killFileTimer.start(mswait); //Kill in 3/4 period
|
if(!m_diskData) killFileTimer.start(mswait); //Kill in 3/4 period
|
||||||
decodeDone ();
|
decodeDone ();
|
||||||
m_startAnother=m_loopall;
|
m_startAnother=m_loopall;
|
||||||
if(m_bNoMoreFiles) {
|
if(m_bNoMoreFiles) {
|
||||||
MessageBox::information_message(this, tr("No more files to open."));
|
MessageBox::information_message(this, tr("No more files to open."));
|
||||||
m_bNoMoreFiles=false;
|
m_bNoMoreFiles=false;
|
||||||
|
}
|
||||||
|
m_messageDupeCache.clear();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64" or m_mode=="FT8") {
|
if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64" or m_mode=="FT8") {
|
||||||
int n=t.indexOf("f");
|
int n=t.indexOf("f");
|
||||||
if(n<0) n=t.indexOf("d");
|
if(n<0) n=t.indexOf("d");
|
||||||
@ -4219,330 +4221,288 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
|
|
||||||
bool bValidFrame = decodedtext.snr() > -24;
|
bool bValidFrame = decodedtext.snr() > -24;
|
||||||
|
|
||||||
|
// dupe check
|
||||||
|
auto frame = decodedtext.message();
|
||||||
|
auto frameOffset = decodedtext.frequencyOffset();
|
||||||
|
if(m_messageDupeCache.contains(frame)){
|
||||||
|
// check to see if the frequency is near our previous frame
|
||||||
|
auto cachedFreq = m_messageDupeCache.value(frame, 0);
|
||||||
|
if(qAbs(cachedFreq - frameOffset) <= NEAR_THRESHOLD_RX){
|
||||||
|
qDebug() << "duplicate frame from" << cachedFreq << "and" << frameOffset;
|
||||||
|
bValidFrame = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// cache for this decode cycle
|
||||||
|
m_messageDupeCache[frame] = frameOffset;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "valid" << bValidFrame << "decoded text" << decodedtext.message();
|
qDebug() << "valid" << bValidFrame << "decoded text" << decodedtext.message();
|
||||||
|
|
||||||
|
// skip if invalid
|
||||||
|
if(!bValidFrame) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ActivityDetail d = {};
|
ActivityDetail d = {};
|
||||||
CallDetail cd = {};
|
CallDetail cd = {};
|
||||||
CommandDetail cmd = {};
|
CommandDetail cmd = {};
|
||||||
CallDetail td = {};
|
CallDetail td = {};
|
||||||
|
|
||||||
|
// Parse General Activity
|
||||||
//Left (Band activity) window
|
|
||||||
if(bValidFrame) {
|
|
||||||
// Parse General Activity
|
|
||||||
#if 1
|
#if 1
|
||||||
bool shouldParseGeneralActivity = true;
|
bool shouldParseGeneralActivity = true;
|
||||||
if(shouldParseGeneralActivity && !decodedtext.messageWords().isEmpty()){
|
if(shouldParseGeneralActivity && !decodedtext.messageWords().isEmpty()){
|
||||||
int offset = decodedtext.frequencyOffset();
|
int offset = decodedtext.frequencyOffset();
|
||||||
|
|
||||||
if(!m_bandActivity.contains(offset)){
|
if(!m_bandActivity.contains(offset)){
|
||||||
int range = 10;
|
int range = 10;
|
||||||
if(m_nSubMode == Varicode::JS8CallFast){ range = 16; }
|
if(m_nSubMode == Varicode::JS8CallFast){ range = 16; }
|
||||||
if(m_nSubMode == Varicode::JS8CallTurbo){ range = 32; }
|
if(m_nSubMode == Varicode::JS8CallTurbo){ range = 32; }
|
||||||
|
|
||||||
QList<int> offsets = generateOffsets(offset-range, offset+range);
|
QList<int> offsets = generateOffsets(offset-range, offset+range);
|
||||||
|
|
||||||
foreach(int prevOffset, offsets){
|
foreach(int prevOffset, offsets){
|
||||||
if(!m_bandActivity.contains(prevOffset)){ continue; }
|
if(!m_bandActivity.contains(prevOffset)){ continue; }
|
||||||
m_bandActivity[offset] = m_bandActivity[prevOffset];
|
m_bandActivity[offset] = m_bandActivity[prevOffset];
|
||||||
m_bandActivity.remove(prevOffset);
|
m_bandActivity.remove(prevOffset);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//ActivityDetail d = {};
|
//ActivityDetail d = {};
|
||||||
d.isLowConfidence = decodedtext.isLowConfidence();
|
d.isLowConfidence = decodedtext.isLowConfidence();
|
||||||
d.isFree = !decodedtext.isStandardMessage();
|
d.isFree = !decodedtext.isStandardMessage();
|
||||||
d.isCompound = decodedtext.isCompound();
|
d.isCompound = decodedtext.isCompound();
|
||||||
d.isDirected = decodedtext.isDirectedMessage();
|
d.isDirected = decodedtext.isDirectedMessage();
|
||||||
d.bits = decodedtext.bits();
|
d.bits = decodedtext.bits();
|
||||||
d.freq = offset;
|
d.freq = offset;
|
||||||
d.text = decodedtext.message();
|
d.text = decodedtext.message();
|
||||||
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
d.snr = decodedtext.snr();
|
d.snr = decodedtext.snr();
|
||||||
d.isBuffered = false;
|
d.isBuffered = false;
|
||||||
d.tdrift = decodedtext.dt();
|
d.tdrift = decodedtext.dt();
|
||||||
d.mode = currentMode();
|
d.mode = currentMode();
|
||||||
|
|
||||||
// if we have any "first" frame, and a buffer is already established, clear it...
|
// if we have any "first" frame, and a buffer is already established, clear it...
|
||||||
int prevBufferOffset = -1;
|
int prevBufferOffset = -1;
|
||||||
if(((d.bits & Varicode::JS8CallFirst) == Varicode::JS8CallFirst) && hasExistingMessageBuffer(d.freq, true, &prevBufferOffset)){
|
if(((d.bits & Varicode::JS8CallFirst) == Varicode::JS8CallFirst) && hasExistingMessageBuffer(d.freq, true, &prevBufferOffset)){
|
||||||
qDebug() << "first message encountered, clearing existing buffer" << prevBufferOffset;
|
qDebug() << "first message encountered, clearing existing buffer" << prevBufferOffset;
|
||||||
m_messageBuffer.remove(d.freq);
|
m_messageBuffer.remove(d.freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a data frame, and a message buffer has been established, buffer it...
|
// if we have a data frame, and a message buffer has been established, buffer it...
|
||||||
if(hasExistingMessageBuffer(d.freq, true, &prevBufferOffset) && !decodedtext.isCompound() && !decodedtext.isDirectedMessage()){
|
if(hasExistingMessageBuffer(d.freq, true, &prevBufferOffset) && !decodedtext.isCompound() && !decodedtext.isDirectedMessage()){
|
||||||
qDebug() << "buffering data" << d.freq << d.text;
|
qDebug() << "buffering data" << d.freq << d.text;
|
||||||
d.isBuffered = true;
|
d.isBuffered = true;
|
||||||
m_messageBuffer[d.freq].msgs.append(d);
|
m_messageBuffer[d.freq].msgs.append(d);
|
||||||
// TODO: incremental display if it's "to" me.
|
// TODO: incremental display if it's "to" me.
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rxActivityQueue.append(d);
|
m_rxActivityQueue.append(d);
|
||||||
m_bandActivity[offset].append(d);
|
m_bandActivity[offset].append(d);
|
||||||
while(m_bandActivity[offset].count() > 10){
|
while(m_bandActivity[offset].count() > 10){
|
||||||
m_bandActivity[offset].removeFirst();
|
m_bandActivity[offset].removeFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Process compound callsign commands (put them in cache)"
|
// Process compound callsign commands (put them in cache)"
|
||||||
#if 1
|
#if 1
|
||||||
qDebug() << "decoded" << decodedtext.frameType() << decodedtext.isCompound() << decodedtext.isDirectedMessage() << decodedtext.isHeartbeat();
|
qDebug() << "decoded" << decodedtext.frameType() << decodedtext.isCompound() << decodedtext.isDirectedMessage() << decodedtext.isHeartbeat();
|
||||||
bool shouldProcessCompound = true;
|
bool shouldProcessCompound = true;
|
||||||
if(shouldProcessCompound && decodedtext.isCompound() && !decodedtext.isDirectedMessage()){
|
if(shouldProcessCompound && decodedtext.isCompound() && !decodedtext.isDirectedMessage()){
|
||||||
cd.call = decodedtext.compoundCall();
|
cd.call = decodedtext.compoundCall();
|
||||||
cd.grid = decodedtext.extra(); // compound calls via pings may contain grid...
|
cd.grid = decodedtext.extra(); // compound calls via pings may contain grid...
|
||||||
cd.snr = decodedtext.snr();
|
cd.snr = decodedtext.snr();
|
||||||
cd.freq = decodedtext.frequencyOffset();
|
cd.freq = decodedtext.frequencyOffset();
|
||||||
cd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
cd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
cd.bits = decodedtext.bits();
|
cd.bits = decodedtext.bits();
|
||||||
cd.tdrift = decodedtext.dt();
|
cd.tdrift = decodedtext.dt();
|
||||||
cd.mode = currentMode();
|
cd.mode = currentMode();
|
||||||
|
|
||||||
// Only respond to HEARTBEATS...remember that CQ messages are "Alt" pings
|
// Only respond to HEARTBEATS...remember that CQ messages are "Alt" pings
|
||||||
if(decodedtext.isHeartbeat()){
|
if(decodedtext.isHeartbeat()){
|
||||||
if(decodedtext.isAlt()){
|
if(decodedtext.isAlt()){
|
||||||
// this is a cq with a standard or compound call, ala "KN4CRD/P: CQCQCQ"
|
// this is a cq with a standard or compound call, ala "KN4CRD/P: CQCQCQ"
|
||||||
cd.cqTimestamp = DriftingDateTime::currentDateTimeUtc();
|
cd.cqTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
|
|
||||||
// it is not processed elsewhere, so we need to just log it here.
|
// it is not processed elsewhere, so we need to just log it here.
|
||||||
logCallActivity(cd, true);
|
logCallActivity(cd, true);
|
||||||
|
|
||||||
// notification for cq
|
// notification for cq
|
||||||
tryNotify("cq");
|
tryNotify("cq");
|
||||||
|
|
||||||
} else {
|
|
||||||
// convert HEARTBEAT to a directed command and process...
|
|
||||||
cmd.from = cd.call;
|
|
||||||
cmd.to = "@ALLCALL";
|
|
||||||
cmd.cmd = " HB";
|
|
||||||
cmd.snr = cd.snr;
|
|
||||||
cmd.bits = cd.bits;
|
|
||||||
cmd.grid = cd.grid;
|
|
||||||
cmd.freq = cd.freq;
|
|
||||||
cmd.utcTimestamp = cd.utcTimestamp;
|
|
||||||
cmd.tdrift = cd.tdrift;
|
|
||||||
cmd.mode = cd.mode;
|
|
||||||
m_rxCommandQueue.append(cmd);
|
|
||||||
|
|
||||||
// notification for hb
|
|
||||||
tryNotify("hb");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "buffering compound call" << cd.freq << cd.call << cd.bits;
|
// convert HEARTBEAT to a directed command and process...
|
||||||
|
cmd.from = cd.call;
|
||||||
hasExistingMessageBuffer(cd.freq, true, nullptr);
|
cmd.to = "@ALLCALL";
|
||||||
m_messageBuffer[cd.freq].compound.append(cd);
|
cmd.cmd = " HB";
|
||||||
}
|
cmd.snr = cd.snr;
|
||||||
}
|
cmd.bits = cd.bits;
|
||||||
#endif
|
cmd.grid = cd.grid;
|
||||||
|
cmd.freq = cd.freq;
|
||||||
// Parse commands
|
cmd.utcTimestamp = cd.utcTimestamp;
|
||||||
// KN4CRD K1JT ?
|
cmd.tdrift = cd.tdrift;
|
||||||
#if 1
|
cmd.mode = cd.mode;
|
||||||
bool shouldProcessDirected = true;
|
|
||||||
if(shouldProcessDirected && decodedtext.isDirectedMessage()){
|
|
||||||
auto parts = decodedtext.directedMessage();
|
|
||||||
|
|
||||||
cmd.from = parts.at(0);
|
|
||||||
cmd.to = parts.at(1);
|
|
||||||
cmd.cmd = parts.at(2);
|
|
||||||
cmd.freq = decodedtext.frequencyOffset();
|
|
||||||
cmd.snr = decodedtext.snr();
|
|
||||||
cmd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
|
||||||
cmd.bits = decodedtext.bits();
|
|
||||||
cmd.extra = parts.length() > 2 ? parts.mid(3).join(" ") : "";
|
|
||||||
cmd.tdrift = decodedtext.dt();
|
|
||||||
cmd.mode = currentMode();
|
|
||||||
|
|
||||||
// if the command is a buffered command and its not the last frame OR we have from or to in a separate message (compound call)
|
|
||||||
if((Varicode::isCommandBuffered(cmd.cmd) && (cmd.bits & Varicode::JS8CallLast) != Varicode::JS8CallLast) || cmd.from == "<....>" || cmd.to == "<....>"){
|
|
||||||
qDebug() << "buffering cmd" << cmd.freq << cmd.cmd << cmd.from << cmd.to;
|
|
||||||
|
|
||||||
// log complete buffered callsigns immediately
|
|
||||||
if(cmd.from != "<....>" && cmd.to != "<....>"){
|
|
||||||
CallDetail cmdcd = {};
|
|
||||||
cmdcd.call = cmd.from;
|
|
||||||
cmdcd.bits = cmd.bits;
|
|
||||||
cmdcd.snr = cmd.snr;
|
|
||||||
cmdcd.freq = cmd.freq;
|
|
||||||
cmdcd.utcTimestamp = cmd.utcTimestamp;
|
|
||||||
cmdcd.ackTimestamp = cmd.to == m_config.my_callsign() ? cmd.utcTimestamp : QDateTime{};
|
|
||||||
cmdcd.tdrift = cmd.tdrift;
|
|
||||||
cmdcd.mode = currentMode();
|
|
||||||
logCallActivity(cmdcd, false);
|
|
||||||
logHeardGraph(cmd.from, cmd.to);
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge any existing buffer to this frequency
|
|
||||||
hasExistingMessageBuffer(cmd.freq, true, nullptr);
|
|
||||||
|
|
||||||
if(cmd.to == m_config.my_callsign()){
|
|
||||||
d.shouldDisplay = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_messageBuffer[cmd.freq].cmd = cmd;
|
|
||||||
m_messageBuffer[cmd.freq].msgs.clear();
|
|
||||||
} else {
|
|
||||||
m_rxCommandQueue.append(cmd);
|
m_rxCommandQueue.append(cmd);
|
||||||
}
|
|
||||||
|
|
||||||
// check to see if this is a station we've heard 3rd party
|
// notification for hb
|
||||||
bool shouldCaptureThirdPartyCallsigns = false;
|
tryNotify("hb");
|
||||||
if(shouldCaptureThirdPartyCallsigns && Radio::base_callsign(cmd.to) != Radio::base_callsign(m_config.my_callsign())){
|
|
||||||
QString relayCall = QString("%1|%2").arg(Radio::base_callsign(cmd.from)).arg(Radio::base_callsign(cmd.to));
|
|
||||||
int snr = -100;
|
|
||||||
if(parts.length() == 4){
|
|
||||||
snr = QString(parts.at(3)).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
//CallDetail td = {};
|
|
||||||
td.through = cmd.from;
|
|
||||||
td.call = cmd.to;
|
|
||||||
td.grid = "";
|
|
||||||
td.snr = snr;
|
|
||||||
td.freq = cmd.freq;
|
|
||||||
td.utcTimestamp = cmd.utcTimestamp;
|
|
||||||
td.tdrift = cmd.tdrift;
|
|
||||||
td.mode = currentMode();
|
|
||||||
logCallActivity(td, true);
|
|
||||||
logHeardGraph(cmd.from, cmd.to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Parse CQs
|
|
||||||
#if 0
|
|
||||||
bool shouldParseCQs = true;
|
|
||||||
if(shouldParseCQs && decodedtext.isStandardMessage()){
|
|
||||||
QString theircall;
|
|
||||||
QString theirgrid;
|
|
||||||
decodedtext.deCallAndGrid(theircall, theirgrid);
|
|
||||||
|
|
||||||
QStringList calls = Varicode::parseCallsigns(theircall);
|
|
||||||
if(!calls.isEmpty() && !calls.first().isEmpty()){
|
|
||||||
theircall = calls.first();
|
|
||||||
|
|
||||||
CallDetail d = {};
|
|
||||||
d.bits = decodedtext.bits();
|
|
||||||
d.call = theircall;
|
|
||||||
d.grid = theirgrid;
|
|
||||||
d.snr = decodedtext.snr();
|
|
||||||
d.freq = decodedtext.frequencyOffset();
|
|
||||||
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
|
||||||
m_callActivity[d.call] = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Parse standard message callsigns
|
|
||||||
// K1JT KN4CRD EM73
|
|
||||||
// KN4CRD K1JT -21
|
|
||||||
// K1JT KN4CRD R-12
|
|
||||||
// DE KN4CRD
|
|
||||||
// KN4CRD
|
|
||||||
#if 0
|
|
||||||
bool shouldParseCallsigns = false;
|
|
||||||
if(shouldParseCallsigns){
|
|
||||||
QStringList callsigns = Varicode::parseCallsigns(decodedtext.message());
|
|
||||||
if(!callsigns.isEmpty()){
|
|
||||||
// one callsign
|
|
||||||
// de [from]
|
|
||||||
// cq [from]
|
|
||||||
|
|
||||||
// two callsigns
|
|
||||||
// [from]: [to] ...
|
|
||||||
// [to] [from] [grid|signal]
|
|
||||||
|
|
||||||
QStringList grids = Varicode::parseGrids(decodedtext.message());
|
|
||||||
|
|
||||||
// one callsigns are handled above... so we only need to handle two callsigns if it's a standard message
|
|
||||||
if(decodedtext.isStandardMessage()){
|
|
||||||
if(callsigns.length() == 2){
|
|
||||||
auto de_callsign = callsigns.last();
|
|
||||||
|
|
||||||
// TODO: jsherer - put this in a function to record a callsign...
|
|
||||||
CallDetail d;
|
|
||||||
d.call = de_callsign;
|
|
||||||
d.grid = !grids.empty() ? grids.first() : "";
|
|
||||||
d.snr = decodedtext.snr();
|
|
||||||
d.freq = decodedtext.frequencyOffset();
|
|
||||||
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
|
||||||
m_callActivity[Radio::base_callsign(de_callsign)] = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//Right (Rx Frequency) window
|
|
||||||
bool bDisplayRight=bAvgMsg;
|
|
||||||
int audioFreq=decodedtext.frequencyOffset();
|
|
||||||
|
|
||||||
if(abs(audioFreq - m_wideGraph->rxFreq()) <= 10){
|
|
||||||
bDisplayRight=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bDisplayRight) {
|
|
||||||
// This msg is within 10 hertz of our tuned frequency, or a JT4 or JT65 avg,
|
|
||||||
// or contains MyCall
|
|
||||||
ui->decodedTextBrowser2->displayDecodedText(decodedtext,m_baseCall,false,
|
|
||||||
m_logBook,m_config.color_CQ(),m_config.color_MyCall(),
|
|
||||||
m_config.color_DXCC(),m_config.color_NewCall(),m_config.ppfx());
|
|
||||||
|
|
||||||
if(m_mode!="JT4") {
|
|
||||||
bool b65=decodedtext.isJT65();
|
|
||||||
if(b65 and m_modeTx!="JT65") on_pbTxMode_clicked();
|
|
||||||
if(!b65 and m_modeTx=="JT65") on_pbTxMode_clicked();
|
|
||||||
}
|
|
||||||
m_QSOText = decodedtext.string ().trimmed ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_mode!="FT8" or !m_config.bHound()) {
|
|
||||||
postDecode (true, decodedtext.string ());
|
|
||||||
|
|
||||||
// find and extract any report for myCall, but save in m_rptRcvd only if it's from DXcall
|
|
||||||
QString rpt;
|
|
||||||
bool stdMsg = decodedtext.report(m_baseCall,
|
|
||||||
Radio::base_callsign(ui->dxCallEntry->text()), rpt);
|
|
||||||
QString deCall;
|
|
||||||
QString grid;
|
|
||||||
decodedtext.deCallAndGrid(/*out*/deCall,grid);
|
|
||||||
{
|
|
||||||
QString t=Radio::base_callsign(ui->dxCallEntry->text());
|
|
||||||
if((t==deCall or t=="") and rpt!="") m_rptRcvd=rpt;
|
|
||||||
}
|
|
||||||
// extract details and send to PSKreporter
|
|
||||||
int nsec=DriftingDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
|
|
||||||
bool okToPost=(nsec>(4*m_TRperiod)/5);
|
|
||||||
|
|
||||||
//if (stdMsg && okToPost) pskPost(decodedtext);
|
|
||||||
|
|
||||||
if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) {
|
|
||||||
if(m_msgAvgWidget->isVisible()) {
|
|
||||||
QFile f(m_config.temp_dir ().absoluteFilePath ("avemsg.txt"));
|
|
||||||
if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
QTextStream s(&f);
|
|
||||||
QString t=s.readAll();
|
|
||||||
m_msgAvgWidget->displayAvg(t);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} else {
|
||||||
|
qDebug() << "buffering compound call" << cd.freq << cd.call << cd.bits;
|
||||||
|
|
||||||
|
hasExistingMessageBuffer(cd.freq, true, nullptr);
|
||||||
|
m_messageBuffer[cd.freq].compound.append(cd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
// Parse commands
|
||||||
|
// KN4CRD K1JT ?
|
||||||
|
#if 1
|
||||||
|
bool shouldProcessDirected = true;
|
||||||
|
if(shouldProcessDirected && decodedtext.isDirectedMessage()){
|
||||||
|
auto parts = decodedtext.directedMessage();
|
||||||
|
|
||||||
|
cmd.from = parts.at(0);
|
||||||
|
cmd.to = parts.at(1);
|
||||||
|
cmd.cmd = parts.at(2);
|
||||||
|
cmd.freq = decodedtext.frequencyOffset();
|
||||||
|
cmd.snr = decodedtext.snr();
|
||||||
|
cmd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
|
cmd.bits = decodedtext.bits();
|
||||||
|
cmd.extra = parts.length() > 2 ? parts.mid(3).join(" ") : "";
|
||||||
|
cmd.tdrift = decodedtext.dt();
|
||||||
|
cmd.mode = currentMode();
|
||||||
|
|
||||||
|
// if the command is a buffered command and its not the last frame OR we have from or to in a separate message (compound call)
|
||||||
|
if((Varicode::isCommandBuffered(cmd.cmd) && (cmd.bits & Varicode::JS8CallLast) != Varicode::JS8CallLast) || cmd.from == "<....>" || cmd.to == "<....>"){
|
||||||
|
qDebug() << "buffering cmd" << cmd.freq << cmd.cmd << cmd.from << cmd.to;
|
||||||
|
|
||||||
|
// log complete buffered callsigns immediately
|
||||||
|
if(cmd.from != "<....>" && cmd.to != "<....>"){
|
||||||
|
CallDetail cmdcd = {};
|
||||||
|
cmdcd.call = cmd.from;
|
||||||
|
cmdcd.bits = cmd.bits;
|
||||||
|
cmdcd.snr = cmd.snr;
|
||||||
|
cmdcd.freq = cmd.freq;
|
||||||
|
cmdcd.utcTimestamp = cmd.utcTimestamp;
|
||||||
|
cmdcd.ackTimestamp = cmd.to == m_config.my_callsign() ? cmd.utcTimestamp : QDateTime{};
|
||||||
|
cmdcd.tdrift = cmd.tdrift;
|
||||||
|
cmdcd.mode = currentMode();
|
||||||
|
logCallActivity(cmdcd, false);
|
||||||
|
logHeardGraph(cmd.from, cmd.to);
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge any existing buffer to this frequency
|
||||||
|
hasExistingMessageBuffer(cmd.freq, true, nullptr);
|
||||||
|
|
||||||
|
if(cmd.to == m_config.my_callsign()){
|
||||||
|
d.shouldDisplay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_messageBuffer[cmd.freq].cmd = cmd;
|
||||||
|
m_messageBuffer[cmd.freq].msgs.clear();
|
||||||
|
} else {
|
||||||
|
m_rxCommandQueue.append(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if this is a station we've heard 3rd party
|
||||||
|
bool shouldCaptureThirdPartyCallsigns = false;
|
||||||
|
if(shouldCaptureThirdPartyCallsigns && Radio::base_callsign(cmd.to) != Radio::base_callsign(m_config.my_callsign())){
|
||||||
|
QString relayCall = QString("%1|%2").arg(Radio::base_callsign(cmd.from)).arg(Radio::base_callsign(cmd.to));
|
||||||
|
int snr = -100;
|
||||||
|
if(parts.length() == 4){
|
||||||
|
snr = QString(parts.at(3)).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
//CallDetail td = {};
|
||||||
|
td.through = cmd.from;
|
||||||
|
td.call = cmd.to;
|
||||||
|
td.grid = "";
|
||||||
|
td.snr = snr;
|
||||||
|
td.freq = cmd.freq;
|
||||||
|
td.utcTimestamp = cmd.utcTimestamp;
|
||||||
|
td.tdrift = cmd.tdrift;
|
||||||
|
td.mode = currentMode();
|
||||||
|
logCallActivity(td, true);
|
||||||
|
logHeardGraph(cmd.from, cmd.to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Parse CQs
|
||||||
|
#if 0
|
||||||
|
bool shouldParseCQs = true;
|
||||||
|
if(shouldParseCQs && decodedtext.isStandardMessage()){
|
||||||
|
QString theircall;
|
||||||
|
QString theirgrid;
|
||||||
|
decodedtext.deCallAndGrid(theircall, theirgrid);
|
||||||
|
|
||||||
|
QStringList calls = Varicode::parseCallsigns(theircall);
|
||||||
|
if(!calls.isEmpty() && !calls.first().isEmpty()){
|
||||||
|
theircall = calls.first();
|
||||||
|
|
||||||
|
CallDetail d = {};
|
||||||
|
d.bits = decodedtext.bits();
|
||||||
|
d.call = theircall;
|
||||||
|
d.grid = theirgrid;
|
||||||
|
d.snr = decodedtext.snr();
|
||||||
|
d.freq = decodedtext.frequencyOffset();
|
||||||
|
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
|
m_callActivity[d.call] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Parse standard message callsigns
|
||||||
|
// K1JT KN4CRD EM73
|
||||||
|
// KN4CRD K1JT -21
|
||||||
|
// K1JT KN4CRD R-12
|
||||||
|
// DE KN4CRD
|
||||||
|
// KN4CRD
|
||||||
|
#if 0
|
||||||
|
bool shouldParseCallsigns = false;
|
||||||
|
if(shouldParseCallsigns){
|
||||||
|
QStringList callsigns = Varicode::parseCallsigns(decodedtext.message());
|
||||||
|
if(!callsigns.isEmpty()){
|
||||||
|
// one callsign
|
||||||
|
// de [from]
|
||||||
|
// cq [from]
|
||||||
|
|
||||||
|
// two callsigns
|
||||||
|
// [from]: [to] ...
|
||||||
|
// [to] [from] [grid|signal]
|
||||||
|
|
||||||
|
QStringList grids = Varicode::parseGrids(decodedtext.message());
|
||||||
|
|
||||||
|
// one callsigns are handled above... so we only need to handle two callsigns if it's a standard message
|
||||||
|
if(decodedtext.isStandardMessage()){
|
||||||
|
if(callsigns.length() == 2){
|
||||||
|
auto de_callsign = callsigns.last();
|
||||||
|
|
||||||
|
// TODO: jsherer - put this in a function to record a callsign...
|
||||||
|
CallDetail d;
|
||||||
|
d.call = de_callsign;
|
||||||
|
d.grid = !grids.empty() ? grids.first() : "";
|
||||||
|
d.snr = decodedtext.snr();
|
||||||
|
d.freq = decodedtext.frequencyOffset();
|
||||||
|
d.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||||
|
m_callActivity[Radio::base_callsign(de_callsign)] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// See MainWindow::postDecode for displaying the latest decodes
|
// See MainWindow::postDecode for displaying the latest decodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,6 +836,7 @@ private:
|
|||||||
QDateTime date;
|
QDateTime date;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QMap<QString, int> m_messageDupeCache; // message frame -> freq offset seen
|
||||||
QMap<QString, QVariant> m_showColumnsCache; // table column:key -> show boolean
|
QMap<QString, QVariant> m_showColumnsCache; // table column:key -> show boolean
|
||||||
QMap<QString, QVariant> m_sortCache; // table key -> sort by
|
QMap<QString, QVariant> m_sortCache; // table key -> sort by
|
||||||
QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent
|
QPriorityQueue<PrioritizedMessage> m_txMessageQueue; // messages to be sent
|
||||||
|
Loading…
Reference in New Issue
Block a user