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
	 Jordan Sherer
						Jordan Sherer