Blob Blame History Raw
From 47dc7b508fa084cd79f57a35365f4306d7764715 Mon Sep 17 00:00:00 2001
From: Petr Hlozek <petr@petrhlozek.cz>
Date: Wed, 30 Oct 2019 19:57:11 +0100
Subject: [PATCH 1/2] Comment to QSO is limited to 120 charactes

---
 src/fAdifImport.pas | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/fAdifImport.pas b/src/fAdifImport.pas
index 81c8acf..af97acc 100644
--- a/src/fAdifImport.pas
+++ b/src/fAdifImport.pas
@@ -387,6 +387,7 @@ function TfrmAdifImport.saveNewEntryFromADIFinDatabase(var d:TnewQSOEntry; var e
       d.COMMENT := edtRemarks.Text + ' ' + d.COMMENT;
     if d.TX_PWR = '' then
       d.TX_PWR := FMyPower;
+    d.COMMENT := copy(d.COMMENT, 1, 200);
 
     d.MODE := UpperCase(d.MODE);
 

From 6a3ea4fffd984a09fab853eae2a7a3352f41d0a1 Mon Sep 17 00:00:00 2001
From: OH1KH <oh1kh@sral.fi>
Date: Fri, 1 Nov 2019 09:40:33 +0200
Subject: [PATCH 2/2] Fix for JTDX logging

This fixes bug that is caused because JTDX udp frame #5 (logging) does not have all tags that are listed in WSJT-X udp format definition leaving the contest part of logging away.

Fix finds out from frame id that it is from JTDX and does not try to find contest tags then.

Other improvement is buffer pointer range check so that it cannot grow over buffer size. If buffer end is reached before all tags are decoded fetching them now results either 0 (zero) or '' (empty string).
This should help also other unstandard udp messages received in future.

Squashed commit of the following:

commit 758b76d95c2b647122563475d0d4b14a974bb8f4
Author: OH1KH <oh1kh@sral.fi>
Date:   Wed Oct 30 18:16:29 2019 +0200

    A bit better pointer check

commit 03a7700e6987481f08e42c30a41df33aa88b0627
Merge: cd79309 935a009
Author: OH1KH <oh1kh@sral.fi>
Date:   Mon Oct 28 17:13:31 2019 +0200

    Merge branch 'master' into jtdx2

commit cd79309e17eec9819e5caf66890b5e49a91abb5d
Author: OH1KH <oh1kh@sral.fi>
Date:   Sun Oct 27 17:14:15 2019 +0200

    WSJT-X: no contest tail if frame from JTDX. Fixed buffer pointer overflow if UDP frame is not within WSJT-X specifications.
---
 src/fNewQSO.lfm |   2 +-
 src/fNewQSO.pas | 166 ++++++++++++++++++++++++++++++------------------
 2 files changed, 104 insertions(+), 64 deletions(-)

diff --git a/src/fNewQSO.lfm b/src/fNewQSO.lfm
index c22b7f4..2ef08b7 100644
--- a/src/fNewQSO.lfm
+++ b/src/fNewQSO.lfm
@@ -1,7 +1,7 @@
 object frmNewQSO: TfrmNewQSO
   Left = 159
   Height = 709
-  Top = 208
+  Top = 64
   Width = 997
   HelpType = htKeyword
   HelpKeyword = 'help/index.html'
diff --git a/src/fNewQSO.pas b/src/fNewQSO.pas
index 4f8b7eb..702236d 100644
--- a/src/fNewQSO.pas
+++ b/src/fNewQSO.pas
@@ -2207,6 +2207,8 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
   TXOn     : Boolean;
   i        : word;
   TXmode   : String;
+  RemoteName :String;
+  BufEnd     : Boolean;
 
   call  : String;
   sname : String;
@@ -2227,19 +2229,41 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
   ExchR  : String;
   ExchS  : String;
 
+  Procedure MoveIndex(m:integer);    //within Buf limits
+  Begin
+     index := index+m;
+     if (index >= length(Buf) ) then
+      Begin
+       //we can not find anything from Buf any more
+       index := length(Buf);
+       BufEnd :=true;
+      end
+     else BufEnd := false;
+  end;
+
   function ui32Buf(var index:integer):uint32;
   begin
+    if BufEnd then
+      Begin
+       Result := 0;
+       exit;
+      end;
     Result := $01000000*ord(Buf[index])
               + $00010000*ord(Buf[index+1])
               + $00000100*ord(Buf[index+2])
               + ord(Buf[index+3]);         // 32-bit unsigned int BigEndian
-    index := index+4                        //point to next element
+    MoveIndex(4);                 //point to next element
   end;
 
   function StrBuf(var index:integer):String;
   var
     P : uint32;
   begin
+    if BufEnd then
+      Begin
+       Result := '';
+       exit;
+      end;
     P := ui32Buf(index);                 //string length;   4bytes
     if P = $FFFFFFFF then               //exeption: empty Qstring len: $FFFF FFFF content: empty
     begin
@@ -2247,7 +2271,7 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
     end
     else begin
       Result := copy(Buf,index,P);        //string content
-      index := index + P                 //point to next element
+      MoveIndex(P);              //point to next element
     end
   end;
 
@@ -2267,7 +2291,7 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
 
   function int64Buf(var index:integer):int64;
   begin
-     REsult := ui64Buf(index)
+     Result := ui64Buf(index)
   end;
 
   function int32Buf(var index:integer):int32;
@@ -2277,14 +2301,24 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
 
   function ui8Buf(var index:integer):uint8;
   begin
+    if BufEnd then
+      Begin
+       Result := 0;
+       exit;
+      end;
     Result := ord(Buf[index]);
-    inc(index)
+    MoveIndex(1)
   end;
 
   function BoolBuf(var index:integer):Boolean;
   begin
+    if BufEnd then
+      Begin
+       Result := false;
+       exit;
+      end;
     Result := ord(Buf[index]) = 1;
-    inc(index)
+    MoveIndex(1)
   end;
 //-------------------------------------------------------------------
 
@@ -2308,6 +2342,7 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
   if WsjtxSock.lasterror=0 then
   begin
     Fox2Line := 0;
+    BufEnd := false;
     index := pos(#$ad+#$bc+#$cb+#$da,Buf); //QTheader: magic number 0xadbccbda
     if index < 1 then
              begin
@@ -2319,7 +2354,7 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
 
     if dmData.DebugLevel>=1 then Writeln('-----------------------decode start---------------------------------');
     if dmData.DebugLevel>=1 then Write('Header position:',index);
-    index:=index+4;  // skip QT header
+    MoveIndex(4);  // skip QT header
 
     ParNum :=  ui32Buf(index);
     if dmData.DebugLevel>=1 then Write(' Schema number:',ParNum);
@@ -2329,7 +2364,7 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
     lblCall.Caption       := 'Wsjt-x remote #'+intToStr(MsgType);   //changed to see last received msgtype
 
     tmpindex := index;
-    ParStr := StrBuf(index);       //read ID to get index point to RepHead end
+    RemoteName := StrBuf(index);       //read remote name to get index point to RepHead end
     RepHead := copy(Buf,1,index-1);
     RepHead[12] := #0;             //Ready made reply header with #0 command (lobyte of uint32)
     index := tmpindex;             //return pointer back
@@ -2735,62 +2770,67 @@ procedure TfrmNewQSO.tmrWsjtxTimer(Sender: TObject);
            ParNum := ui8Buf(index);  //timespec local/utc   (not used in cqrlog)
            if dmData.DebugLevel>=1 then Writeln('timespec: ', ParNum);
            //----------------------------------------------------
-           OpCall := trim(StrBuf(index));  //operator callsign (in contest, club etc.)
-           ExchR :=  trim(StrBuf(index));  //fake, this is actually "My call". Not used
-           ExchR :=  trim(StrBuf(index));  //fake, this is actually "My grid". Not used
-           ExchS :=  trim(StrBuf(index));  //contest exchange sent. report + others
-           ExchR :=  trim(StrBuf(index));  //contest exchange received. report + others
-           //----------------------------------------------------
-           {
-           These wsjt-x will return as contest number:
-             *       0 -> NONE
-             *       1 -> NA VHF
-             *       2 -> EU VHF
-             *       3 -> FIELD DAY
-             *       4 -> RTTY RU
-             *       5 -> FOX
-             *       6 -> HOUND
-             }
-
-           case ContestNr of
-                1         :Begin //NA VHF  EX:locator-4chr
-                            edtContestName.Text := ContestName[ContestNr];
-                            edtContestExchangeMessageReceived.Text := ExchR;
-                            edtContestExchangeMessageSent.Text := ExchS;
-                            edtHisRST.Text := ' '; // NA-VHF has no proper reports (!?!)
-                            edtMyRST.Text := ' ';  // fake space here. Otherwise qso edit sets 599 for reports
-                           end;
-                2         :Begin  //EU VHF    EX:RS-2chr/serial-4chr/ /locator
-                             edtContestName.Text := ContestName[ContestNr];
-                             edtContestSerialReceived.Text := copy(ExchR,3,4);  //serialNr
-                             edtContestExchangeMessageReceived.Text:= copy(ExchR,8,6); //exMsg=locator
-                             edtContestSerialSent.Text := copy(ExchS,3,4);  //serialNr
-                             edtContestExchangeMessageSent.Text:= copy(ExchS,8,6); //exMsg=locator
-                             edtHisRST.Text := edtHisRST.Text+' '; // fake space here. Otherwise qso edit sets xx9 for reports
-                             edtMyRST.Text := edtMyRST.Text+' ';
-                           end;
-                3         :Begin  //FIELD DAY EX:TXnrClass/ /state
-                            edtContestName.Text := ContestName[ContestNr];
-                            edtContestExchangeMessageReceived.Text := ExchR;
-                            edtContestExchangeMessageSent.Text := ExchS;
-                            edtHisRST.Text := ' '; // FD has no proper reports (!?!)
-                            edtMyRST.Text := ' ';  // fake space here. Otherwise qso edit sets 599 for reports
-                           end;
-                4         :Begin  //RTTY RU   EX:RST-3chr/ /serial-4chr[or] state(not numbers)
-                            edtContestName.Text := ContestName[ContestNr];
-                            if  (ExchS[5] in [ 'A' .. 'Z' ]) then
-                              edtContestExchangeMessageSent.Text:= copy(ExchS,5,length(ExchS)) //exMsg=state
-                             else
-                              edtContestSerialSent.Text := copy(ExchS,5,length(ExchS)); //serialNr
-                            if  (ExchR[5] in [ 'A' .. 'Z' ]) then
-                              edtContestExchangeMessageReceived.Text:= copy(ExchR,5,length(ExchR)) //exMsg=state
-                             else
-                              edtContestSerialReceived.Text := copy(ExchR,5,length(ExchR)); //serialNr
-                           end;
-                5,6       : edtContestName.Text := ContestName[ContestNr]+'-QSO';
-           end;
-           case ContestNr of
-                1,2,3,4   :  edtContestSerialReceived.Text := copy( edtContestSerialReceived.Text,1,6); //Max Db length=6
+           if dmData.DebugLevel>=1 then Writeln('Remote name: ', RemoteName);
+           if RemoteName = 'WSJT-X' then   //no contest in JTDX
+            begin
+                 if dmData.DebugLevel>=1 then Writeln('Tail logging part entered');
+                 OpCall := trim(StrBuf(index));  //operator callsign (in contest, club etc.)
+                 ExchR :=  trim(StrBuf(index));  //fake, this is actually "My call". Not used
+                 ExchR :=  trim(StrBuf(index));  //fake, this is actually "My grid". Not used
+                 ExchS :=  trim(StrBuf(index));  //contest exchange sent. report + others
+                 ExchR :=  trim(StrBuf(index));  //contest exchange received. report + others
+                 //----------------------------------------------------
+                 {
+                 These wsjt-x will return as contest number:
+                   *       0 -> NONE
+                   *       1 -> NA VHF
+                   *       2 -> EU VHF
+                   *       3 -> FIELD DAY
+                   *       4 -> RTTY RU
+                   *       5 -> FOX
+                   *       6 -> HOUND
+                   }
+
+                 case ContestNr of
+                      1         :Begin //NA VHF  EX:locator-4chr
+                                  edtContestName.Text := ContestName[ContestNr];
+                                  edtContestExchangeMessageReceived.Text := ExchR;
+                                  edtContestExchangeMessageSent.Text := ExchS;
+                                  edtHisRST.Text := ' '; // NA-VHF has no proper reports (!?!)
+                                  edtMyRST.Text := ' ';  // fake space here. Otherwise qso edit sets 599 for reports
+                                 end;
+                      2         :Begin  //EU VHF    EX:RS-2chr/serial-4chr/ /locator
+                                   edtContestName.Text := ContestName[ContestNr];
+                                   edtContestSerialReceived.Text := copy(ExchR,3,4);  //serialNr
+                                   edtContestExchangeMessageReceived.Text:= copy(ExchR,8,6); //exMsg=locator
+                                   edtContestSerialSent.Text := copy(ExchS,3,4);  //serialNr
+                                   edtContestExchangeMessageSent.Text:= copy(ExchS,8,6); //exMsg=locator
+                                   edtHisRST.Text := edtHisRST.Text+' '; // fake space here. Otherwise qso edit sets xx9 for reports
+                                   edtMyRST.Text := edtMyRST.Text+' ';
+                                 end;
+                      3         :Begin  //FIELD DAY EX:TXnrClass/ /state
+                                  edtContestName.Text := ContestName[ContestNr];
+                                  edtContestExchangeMessageReceived.Text := ExchR;
+                                  edtContestExchangeMessageSent.Text := ExchS;
+                                  edtHisRST.Text := ' '; // FD has no proper reports (!?!)
+                                  edtMyRST.Text := ' ';  // fake space here. Otherwise qso edit sets 599 for reports
+                                 end;
+                      4         :Begin  //RTTY RU   EX:RST-3chr/ /serial-4chr[or] state(not numbers)
+                                  edtContestName.Text := ContestName[ContestNr];
+                                  if  (ExchS[5] in [ 'A' .. 'Z' ]) then
+                                    edtContestExchangeMessageSent.Text:= copy(ExchS,5,length(ExchS)) //exMsg=state
+                                   else
+                                    edtContestSerialSent.Text := copy(ExchS,5,length(ExchS)); //serialNr
+                                  if  (ExchR[5] in [ 'A' .. 'Z' ]) then
+                                    edtContestExchangeMessageReceived.Text:= copy(ExchR,5,length(ExchR)) //exMsg=state
+                                   else
+                                    edtContestSerialReceived.Text := copy(ExchR,5,length(ExchR)); //serialNr
+                                 end;
+                      5,6       : edtContestName.Text := ContestName[ContestNr]+'-QSO';
+                 end;
+                 case ContestNr of
+                      1,2,3,4   :  edtContestSerialReceived.Text := copy( edtContestSerialReceived.Text,1,6); //Max Db length=6
+                 end;
            end;
            //----------------------------------------------------
            if dmData.DebugLevel>=1 then Writeln(' WSJTX decode #5 logging: press save');