Fixed double printing (... I think ...)

This commit is contained in:
Jordan Sherer 2019-10-19 20:30:29 -04:00
parent 54a7085c47
commit 1ad0efa634
6 changed files with 275 additions and 310 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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
} }

View File

@ -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