Fixes for N1MM remote

JS8CALL has changed it's UDP datagrams in version 2.2.2. UDP frame having clear ADIF content has been removed (it still exist in v2.2.2-devel) that stops logging to work with cqrlog's N1MM remote.
They use now JSON based UDP frames but the same ADIF content can be found from inside of logging UDP frame.

To make N1MM remote work with old and new versions of JS8CALL the detecting procedure has bee rewritten.

Naming "N1MM remote" has been changed to "ADIF remote" as there has been misunderstoods that N1MM contest logger could be connected to cqrlog.

ADIF remote can read ADIF tags from UDP datagram as follows:

	- Datagram has full ADIF export including proper header and one or more qso records.(used by wsjt-x primary UDP datagram)
	- Datagram has qso record without header starting with tag "<CALL" and ending to <EOR> (used by wsjt-x secondary UDP datagram)
	- Datagram has JSON record including 'LOG.QSO","value":' followed by ADIF tags starting with tag "<CALL" and ending to '"}'

ADIF remote is tested to work with JS8CALL v.2.2.2 and v2.2.2-devel, WSJT-X UDP server (reads logged message #12 contents), WSJT-X secondary UDP server (former named  N1MM+ remote), Perl test script sending full ADIF UDP datagram having several qso records and headerless ADIF UDP datagram having several qso records.

Help files are fixed to follow new naming.

Squashed commit of the following:

commit 6b7680cf37e0901c20abd25ffab412f91f920fdf
Author: OH1KH <oh1kh@sral.fi>
Date:   Wed Dec 2 09:51:38 2020 +0200

    Fine tuning after testing

commit a02bce3cd5
Author: OH1KH <oh1kh@sral.fi>
Date:   Tue Dec 1 19:19:13 2020 +0200

    small fix

commit 7612263261
Author: OH1KH <oh1kh@sral.fi>
Date:   Tue Dec 1 19:16:00 2020 +0200

    help fix

commit 8d4003b2e6
Author: OH1KH <oh1kh@sral.fi>
Date:   Tue Dec 1 18:45:00 2020 +0200

    Seems to work now as expected.

commit 8413409baa
Author: OH1KH <oh1kh@sral.fi>
Date:   Tue Dec 1 12:57:44 2020 +0200

    Settings to separate adif datagram and json datagram including adif. Help fixes

commit d3fc4b66a0
Author: OH1KH <oh1kh@sral.fi>
Date:   Tue Dec 1 11:26:06 2020 +0200

    Initial naming change from N1MM to ADIF
This commit is contained in:
OH1KH 2020-12-02 10:51:26 +02:00
parent 93135f03dd
commit efd0b2fd86
13 changed files with 236 additions and 167 deletions

View File

@ -39,20 +39,27 @@ function goBack() {
<p align=center><img src=img/line.png></p>
<a name=fl1><h2><strong>N1MM logger remote</strong></h2></a>
<img src="img/n1mm1.png" name="1" border="0"/>
<p>N1MM logger remote connection is just for copying logged qso infromation from other program like wsjt-x or js8call (or similars that support this kind of logging) to cqrlog.
<a name=fl1><h2><strong>ADIF logger remote</strong></h2></a>
<img src="img/adif1.png" name="1" border="0"/>
<p>ADIF remote connection (former "N1MM+ remote logger") is just for copying logged qso infromation from other program like wsjt-x or js8call (or similars that support this kind of logging) to cqrlog.
There is no other finctionality than just transfer the logged data.
<br><br> ADIF remote can read adif tags from UDP datagram as follows:
<ul>
<li> Datagram has full adif export including proper header and one or more qso records.(used by wsjt-x primary UDP datagram)</li>
<li> Datagram has qso record without header starting with tag "&lt;CALL" and ending to &lt;EOR&gt; (used by wsjt-x secondary UDP datagram)</li>
<li> Datagram has JSON record including 'LOG.QSO","value":' followed by adif tags starting with tag "&lt;CALL" and ending to '"}'</li>
</ul>
</br>Remote mode is activated from NewQSO/File selection list, or pressing Ctrl-K when NewQSO window is focused.
</p><p>
<img src="img/n1mm3.png" name="3" border="0"/>
<img src="img/adif3.png" name="3" border="0"/>
</br>Settings must be done at wsjt-x or js8call Settings/reporting. At least checking the checkbox. Port and address values can be defaults.
</p><p>
<img src="img/n1mm2.png" name="2" border="0"/></br>
<img src="img/adif2.png" name="2" border="0"/></br>
No indication of logging can be seen unless user has set "cqrlog/preferences/NewQSO/Show recent qso records for last X days" active.</br>
If this is set, after pressing "OK" at companion program's logging window logged qso will appear to cqrlog's NewQSO recent qsos list.
If QSO list window is open and "cqrlog/preferences/NewQSQ/Refresh data after save qso" is checked QSO list is also updated after QSO is logged.
</p><p>
N1MM remote can not be used at same time as fldigi or wsjt remotes.</br> How ever if you allow N1MM logger support at wsjt-x and js8call settings and choose remote mode for N1MM from cqrlog you can keep both programs running at same time if your rigctld settings support that.
ADIF remote can not be used at same time as fldigi or wsjt remotes.</br> How ever if you allow ADIF logger support at wsjt-x and js8call settings and choose remote mode for ADIF from cqrlog you can keep both programs running at same time if your rigctld settings support that.
See: <a href="img/setting_rigctld_for_all_programs.pdf">setting_rigctld_for_all_programs</a>, and log qsos from both programs to cqrlog without problems.
</p><p align=center><img src=img/line.png></p>
<br>

View File

@ -57,7 +57,7 @@
<li><a href="h1.html#ch2">fldigi interface</a></li>
<li><a href="fldxml.html">fldigi XmlRpc remote</a></li>
<li><a href="h1.html#ch2b">wsjt-x interface</a></li>
<li><a href="h1.html#ch2c">N1MM interface</a></li>
<li><a href="h1.html#ch2c">ADIF interface</a></li>
<li><a href="h1.html#ch3">Exit & Auto backup</a></li>
<li><a href="h1.html#ch4">External viewers</a></li>
<li><a href="h1.html#ch5">Callbook support</a></li>
@ -620,19 +620,19 @@ There are no known dependencies issues.<br><br>
Pressing calendar icon is easy way to set date. Double click on selected date closes calendar and sets the date. Pressing ESC closes calendar, but does not set date. Date can also be typed in manually.
<br><br>
<a name=ch2c></a>
<h2><strong>N1MM interface</strong></h2>
Setting of N1MM interface is similar as wsjt-x interface. Only IP address and PORT have to be set if they are not defaults.
<h2><strong>ADIF interface</strong></h2>
Setting of ADIF interface is similar as wsjt-x interface. Only IP address and PORT have to be set if they are not defaults.
<br>Default values are <strong>127.0.0.1</strong> or <strong>localhost</strong> for address and <strong>2333</strong> for port. These are set in wsjt-x, or js8call, settings/reporting and if changed there, must also to be changed here.
<br>
Address can also be other PC's IP address if wsjt-x is running in different networked PC than cqrlog, or even 0.0.0.0 when cqrlog listens all transmits from every wsjt-x in network.
<br><br>
At WSJT-X 2.1.0 settings N1MM remote is renamed to "Secondary UDP server (deprecated)" and it is reported to be removed completely in future. Because of that it is now possible to set cqrlog's N1MM port to wsjt-x UDP server port number. WSJT-X 2.1.x UDP frames contain message #12 that
includes log information in ADIF format and N1MM remote can now parse that from binary data if you do not like to have monitoring properties (using wsjt remote) but want just qso logging (using N1MM remote).
At WSJT-X 2.1.0 settings ADIF remote is renamed to "Secondary UDP server (deprecated)" and it is reported to be removed completely in future. Because of that it is now possible to set cqrlog's ADIF port to wsjt-x UDP server port number. WSJT-X 2.1.x UDP frames contain message #12 that
includes log information in ADIF format and ADIF remote can now parse that from binary data if you do not like to have monitoring properties (using wsjt remote) but want just qso logging (using ADIF remote).
<br><br>
N1MM remote has now better support for QRZ/HamQTH info fetch. If this is not allowed in preferences, or if there is no reponse from Web max waiting time (timeout) is 5 seconds (You can not remove this property, so be patient. You can not have new qso for logging during 5 seconds!).
ADIF remote has now better support for QRZ/HamQTH info fetch. If this is not allowed in preferences, or if there is no reponse from Web max waiting time (timeout) is 5 seconds (You can not remove this property, so be patient. You can not have new qso for logging during 5 seconds!).
<br>While having qso you can write some notes like Name, QTH, Comment to QSO, etc. to NewQSO and it will saved with qso data during next wsjt-x "log qso/OK" event. They will not be overwritten by possible Qrz/HamQth info.
<br><br>
<strong>NOTE !!</strong> Wstx- does not send contest -name, -number and -string in ADIF logging datagram. Contest exchanges are placed to regular rst_s and rst_r strings. So cqrlog can not fill proper contest columns when logging is done with ADIF datagram using N1MM remote.
<strong>NOTE !!</strong> Wstx- does not send contest -name, -number and -string in ADIF logging datagram. Contest exchanges are placed to regular rst_s and rst_r strings. So cqrlog can not fill proper contest columns when logging is done with ADIF datagram using ADIF remote.
<br><br>
<a name=ch3><h2><strong>Exit & Auto backup</strong></h2></a>

View File

@ -95,7 +95,7 @@
</tr>
<tr>
<td width="35%">Ctrl-K</td>
<td width="65%">Remote mode for N1MM logger</td>
<td width="65%">Remote mode for ADIF logger</td>
</tr>
<tr>
<td width="35%">Ctrl-L</td>
@ -441,7 +441,7 @@ best digimode softwares available.<br>
For <em>wsjt-x</em>, setup is done at same tab of preferences as <em>fldigi<em>. For operating with wsjt-x see: <a href="wsjt.html">Wsjt-x operation</a>
<br><br> To use <em>fldigi</em>, CQRLOG must be switched to Remote from the menu File -> Remote mode for fldigi(or Ctrl-M).
<br> To use <em>wsjt-x</em>, CQRLOG must be switched to Remote from the menu File -> Remote mode for wsjt.
<br> To use <em>N1MM logger</em>, CQRLOG must be switched to Remote from the menu File -> Remote mode for N1MM logger.<br><br>
<br> To use <em>ADIF logger</em>, CQRLOG must be switched to Remote from the menu File -> Remote mode for ADIF logger.<br><br>
<img src="img/h104.png"><br><br>
The logging screen changes to indicate that CQRLOG is now working in 'Remote mode!' and
can be controlled either from <em>fldigi</em> or can "dictate" the mode and frequency

BIN
help/img/adif1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
help/img/adif3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -36,7 +36,7 @@
<li><a target="right" href="h28.html">Voice messages</a></li>
<li><a target="right" href="h1.html#ch2">fldigi interface</a></li>
<li><a target="right" href="h1.html#ch2b">wsjt-x interface</a></li>
<li><a target="right" href="h1.html#ch2c">N1MM interface</a></li>
<li><a target="right" href="h1.html#ch2c">ADIF remote interface</a></li>
<li><a target="right" href="h1.html#ch3">Auto backup</a></li>
<li><a target="right" href="h1.html#ch4">External viewers</a></li>
<li><a target="right" href="h1.html#ch5">Callbook support</a></li>
@ -57,7 +57,7 @@
<li><a target="right" href="h26.html#mk2">CW Type</a></li>
<li><a target="right" href="h20.html#ah33">Digital modes:</a> <em>fldigi</em></li>
<li><a target="right" href="fldxml.html">Digital modes:</a> <em>fldigi XmlRpc</em></li>
<li><a target="right" href="n1mm.html">Digital modes:</a> <em>N1MM</em></li>
<li><a target="right" href="adif.html">Digital modes:</a> <em>ADIF remote</em></li>
<li><a target="right" href="wsjt.html">Digital modes:</a> <em>wsjt-x</em></li>
<li><a target="right" href="h21.html#ah19">DX Cluster Operation</a></li>
<li><a target="right" href="h23.html#ah22">Filtering</a></li>

View File

@ -4941,11 +4941,11 @@ object frmNewQSO: TfrmNewQSO
ShortCut = 16458
OnClick = acRemoteWsjtExecute
end
object mnuRemoteModeN1MM: TMenuItem
Action = acRemoteModeN1MM
Caption = 'Remote mode for N1MM logger'
object mnuRemoteModeADIF: TMenuItem
Action = acRemoteModeADIF
Caption = 'Remote mode for ADIF'
ShortCut = 16459
OnClick = acRemoteModeN1MMExecute
OnClick = acRemoteModeADIFExecute
end
object MenuItem59: TMenuItem
Caption = '-'
@ -5774,10 +5774,10 @@ object frmNewQSO: TfrmNewQSO
Caption = 'Contest'
OnExecute = acContestExecute
end
object acRemoteModeN1MM: TAction
object acRemoteModeADIF: TAction
Category = 'File'
Caption = 'N1MM'
OnExecute = acRemoteModeN1MMExecute
Caption = 'ADIF'
OnExecute = acRemoteModeADIFExecute
end
end
object imgMain: TImageList
@ -7267,9 +7267,9 @@ object frmNewQSO: TfrmNewQSO
left = 392
top = 720
end
object tmrN1MM: TTimer
object tmrADIF: TTimer
Enabled = False
OnTimer = tmrN1MMTimer
OnTimer = tmrADIFTimer
left = 800
top = 32
end

View File

@ -32,7 +32,7 @@ const
cCntyVersionCheckUrl = 'http://www.ok2cqr.com/linux/cqrlog/ctyfiles/ver.dat';
type
TRemoteModeType = (rmtFldigi, rmtWsjt, n1mm);
TRemoteModeType = (rmtFldigi, rmtWsjt, rmtADIF);
type
@ -81,7 +81,7 @@ type
acProp: TAction;
acReminder: TAction;
acContest: TAction;
acRemoteModeN1MM: TAction;
acRemoteModeADIF: TAction;
acUploadToAll: TAction;
acUploadToHrdLog: TAction;
acUploadToClubLog: TAction;
@ -142,7 +142,7 @@ type
MenuItem63: TMenuItem;
MenuItem94 : TMenuItem;
mnueQSLView: TMenuItem;
mnuRemoteModeN1MM: TMenuItem;
mnuRemoteModeADIF: TMenuItem;
mnuReminder: TMenuItem;
MenuItem86: TMenuItem;
MenuItem87: TMenuItem;
@ -357,7 +357,7 @@ type
tabDXCCStat : TTabSheet;
tabSatellite : TTabSheet;
tabLOConfig: TTabSheet;
tmrN1MM: TTimer;
tmrADIF: TTimer;
tmrWsjtSpd: TTimer;
tmrWsjtx: TTimer;
tmrUploadAll: TTimer;
@ -388,7 +388,7 @@ type
procedure acSCPExecute(Sender : TObject);
procedure acSendSpotExecute(Sender : TObject);
procedure acShowStatBarExecute(Sender: TObject);
procedure acRemoteModeN1MMExecute(Sender: TObject);
procedure acRemoteModeADIFExecute(Sender: TObject);
procedure acTuneExecute(Sender : TObject);
procedure acUploadToAllExecute(Sender: TObject);
procedure acUploadToClubLogExecute(Sender: TObject);
@ -568,7 +568,7 @@ type
procedure tmrEndStartTimer(Sender: TObject);
procedure tmrEndTimer(Sender: TObject);
procedure tmrFldigiTimer(Sender: TObject);
procedure tmrN1MMTimer(Sender: TObject);
procedure tmrADIFTimer(Sender: TObject);
procedure tmrRadioTimer(Sender: TObject);
procedure tmrStartStartTimer(Sender: TObject);
procedure tmrStartTimer(Sender: TObject);
@ -614,6 +614,7 @@ type
WsjtxDecodeRunning : boolean;
RememberAutoMode : Boolean;
IsJS8Callrmt : Boolean; //way to isolate adif from JS8's JSON
Op : String;
procedure showDOK(stat:boolean);
@ -673,7 +674,7 @@ type
WsjtxSock : TUDPBlockSocket; //receive socket
WsjtxSockS : TUDPBlockSocket; //multicast send socket
N1MMSock : TUDPBlockSocket;
ADIFSock : TUDPBlockSocket;
WsjtxMode : String; //Moved from private
WsjtxBand : String;
@ -683,7 +684,7 @@ type
was_call : String; //holds recent edtCallsign.text before it was cleared
FldigiXmlRpc : Boolean;
AnyRemoteOn : Boolean; //true if any of remotes fldigi,wsjt,or n1mm is active);
AnyRemoteOn : Boolean; //true if any of remotes fldigi,wsjt,or ADIF is active);
ClearAfterFreqChange : Boolean;
ChangeFreqLimit : Double;
@ -2089,111 +2090,171 @@ begin
end;
procedure TfrmNewQSO.tmrN1MMTimer(Sender: TObject);
procedure TfrmNewQSO.tmrADIFTimer(Sender: TObject);
var
Buf,
buf2,
prik,
data:string;
data :string;
chkDuplicates :boolean;
i:longint;
l:integer;
i :longint;
a,b,l :integer;
begin
tmrN1MM.Enabled:=false;
tmrADIF.Enabled:=false;
chkDuplicates:=false;
if N1MMsock.WaitingData > 0 then
if ADIFsock.WaitingData > 0 then
Begin
if dmData.DebugLevel>=1 then Writeln('N1MM has data');
while N1MMsock.WaitingData > 0 do //do all pending messages in one go
if dmData.DebugLevel>=1 then Writeln('rmtADIF has data. JS8CALL mode is now ',IsJS8Callrmt);
while ADIFsock.WaitingData > 0 do //do all pending messages in one go
begin
Buf := N1MMsock.RecvPacket(1000);
if dmData.DebugLevel>=1 then Writeln('N1MM read data');
if N1MMSock.lasterror=0 then
Buf := trim(ADIFsock.RecvPacket(500)); //Read all data waitingtimeout 500ms
if dmData.DebugLevel>=1 then Writeln('rmtADIF read data');
if ADIFSock.lasterror=0 then
begin
//check data. Is there string '<adif_ver'? Might then be wsjt-x's UDP
if pos('<ADIF_VER',uppercase (Buf)) > 0 then
Begin
if dmData.DebugLevel>=1 then writeln('adif_ver found');
Begin //cut all before '<adif_data' away and continue then
data := copy(Buf,pos('<ADIF_VER',uppercase (Buf)),length(Buf));
Buf := data;
end;
end;
//check now that at least tag '<call:' is found. If not throw away...
if pos('<CALL:',uppercase (Buf)) > 0 then
Begin
if dmData.DebugLevel>=1 then writeln(Buf);
//this is fake as call info(qslmgr) needs date. We use current date if call tag comes before qso_date tag
//qso_date will then replace this
edtDate.Text := FormatDateTime('YYYY-MM-DD',now());
repeat
//check data.
//if JS8CALL JSON with ADIF inside
a:= pos('"LOG.QSO","value":"',Buf);
b:= pos('"}',Buf);
if (a>0 ) and (b>0) then
Begin
IsJS8Callrmt:=true; //once this is set it resets only when remote is closed
lblCall.Caption := 'rmt ADIF JS8CALL';
Buf:=copy(Buf,a+19,length(Buf)-a-19-1)+' <eor>';
if dmData.DebugLevel>=1 then writeln('Modified JS8CALL JSON: ',Buf);
end
else
begin
//if not JS8CALL and has proper ADIF header with at least one qso record with CALL and EOR (wsjt-x primary UDP msg #12)
if not IsJS8Callrmt then
Begin
a:=pos('<ADIF_VER',uppercase (Buf));
b:=pos('<EOH>',uppercase (Buf));
if (a>0) and (b>0) then //proper adif block starts with header
Begin
if dmData.DebugLevel>=1 then writeln('ADIF_VER header block found!');
Buf:=copy(Buf,b+5,length(Buf));
a:=pos('<CALL',uppercase (Buf));
b:=pos('<EOR>',uppercase (Buf));
if (b>a) and (a>0) and (b>0) then
Begin
if dmData.DebugLevel>=1 then writeln('There seems to be at least one qso record!')
end
else
Begin
if dmData.DebugLevel>=1 then writeln('There seems to be something wrong with qso record(s)!');
tmrADIF.Enabled:=true;
exit;
end;
end;
//if not JS8CALL and not proper ADIF header but has CALL and EOR (wsjt-x secondary UDP frame)
if (a=0) and (b=0) then
Begin
a:=pos('<CALL',uppercase (Buf));
b:=pos('<EOR>',uppercase (Buf));
if (a>0) and (b>0) then
Begin
if dmData.DebugLevel>=1 then writeln('There seems to be at least one qso record!')
end
else
Begin
if dmData.DebugLevel>=1 then writeln('No qso record(s)!');
tmrADIF.Enabled:=true;
exit;
end;
end;
end
else
Begin //this will block the second adif frame sent by JS8CALL without JSON and ADIF header
tmrADIF.Enabled:=true;
exit;
end;
end; //else JS8CALL with JSON included ADIF
Buf2:=Buf;
//here check if several qsos in block
repeat //here check if several qsos in block
begin
if frmAdifImport.getNextAdifTag(Buf,prik,data) then
if dmData.DebugLevel>=1 then
Begin
write(prik,'->');
writeln(data);
end;
case uppercase(prik) of
'CALL' : Begin
edtCall.Text := uppercase(data);
c_lock :=false;
edtCallExit(nil); //does info fetch
WaitWeb(5); //wait for web response 5sec timeout
end;
'GRIDSQUARE' :Begin
data := uppercase(data);
if dmUtils.IsLocOK(data) then
if pos(data,edtGrid.Text)=0 then //if qso loc does not fit to QRZ loc , or qrz loc is empty
edtGrid.Text := data; //replace qrz loc, otherwise keep it
end;
'MODE' : cmbMode.Text := uppercase(data);
//now this overrides MODE, if exists
'SUBMODE' : cmbMode.Text := uppercase(data);
'FREQ' : cmbFreq.Text := data;
'RST_SENT' : edtHisRST.Text := data;
'RST_RCVD' : edtMyRST.Text := data;
'QSO_DATE' : Begin
edtDate.Text := copy(data,1,4)+'-'+
copy(data,5,2)+'-'+
copy(data,7,2);
end;
'TIME_ON' : edtStartTime.Text := copy(data,1,2)+':'+ copy(data,3,2);
'TIME_OFF': edtStartTime.Text := copy(data,1,2)+':'+ copy(data,3,2);
'TX_PWR' : edtPWR.Text := data;
'NAME' : if edtName.Text='' then edtName.Text := data;
'QTH' : if edtQTH.Text='' then edtQTH.Text := data;
'COMMENT': if edtRemQSO.Text = '' then edtRemQSO.Text := data;
'NAME_INTL' : if edtName.Text='' then edtName.Text := data;
'QTH_INTL' : if edtQTH.Text='' then edtQTH.Text := data;
'COMMENT_INTL': if edtRemQSO.Text = '' then edtRemQSO.Text := data;
'IOTA' : if cmbIOTA.Text = '' then cmbIOTA.Text := data;
'STATE' : if edtState.Text='' then edtState.Text := data;
'CQZ' : edtWaz.Text := data;
'ITUZ' : edtITU.Text := data;
'CONTEST_ID': edtContestName.Text := data;
'STX': edtContestSerialSent.Text := data;
'SRX': edtContestSerialReceived.Text := data;
//N1MM logger+ definition does not have STXString tag. Added anyway(future?).
'STX_STRING':edtContestExchangeMessageSent.Text := data;
//same with SRX
'SRX_STRING': edtContestExchangeMessageReceived.Text:= data;
'OPERATOR': Begin
if ((data<>'') and (Op = UpperCase(cqrini.ReadString('Station', 'Call', '')))) then
Begin
Op := data;
sbNewQSO.Panels[2].Text := cOperator+Op;
end;
end;
end; //case
end; //repeat
b:=pos('<EOR>',uppercase(buf2));
buf:=copy(Buf2,1,b+5); //holds one record
buf2:= copy(buf2,b+6,length(buf2)); //holds remaining records
//check now that at least tag '<call:' is found. If not throw away...
if pos('<CALL:',uppercase (Buf)) > 0 then
Begin
if dmData.DebugLevel>=1 then writeln('Handle qso record: ',Buf);
//this is fake as call info(qslmgr) needs date. We use current date if call tag comes before qso_date tag
//qso_date will then replace this
edtDate.Text := FormatDateTime('YYYY-MM-DD',now());
repeat
begin
if frmAdifImport.getNextAdifTag(Buf,prik,data) then
if dmData.DebugLevel>=1 then
Begin
write(prik,'->');
writeln(data);
end;
case uppercase(prik) of
'CALL' : Begin
edtCall.Text := uppercase(data);
c_lock :=false;
edtCallExit(nil); //does info fetch
WaitWeb(5); //wait for web response 5sec timeout
end;
'GRIDSQUARE' :Begin
data := uppercase(data);
if dmUtils.IsLocOK(data) then
if pos(data,edtGrid.Text)=0 then //if qso loc does not fit to QRZ loc , or qrz loc is empty
edtGrid.Text := data; //replace qrz loc, otherwise keep it
end;
'MODE' : cmbMode.Text := uppercase(data);
//now this overrides MODE, if exists
'SUBMODE' : cmbMode.Text := uppercase(data);
'FREQ' : cmbFreq.Text := data;
'RST_SENT' : edtHisRST.Text := data;
'RST_RCVD' : edtMyRST.Text := data;
'QSO_DATE' : Begin
edtDate.Text := copy(data,1,4)+'-'+
copy(data,5,2)+'-'+
copy(data,7,2);
end;
'TIME_ON' : edtStartTime.Text := copy(data,1,2)+':'+ copy(data,3,2);
'TIME_OFF' : edtEndTime.Text := copy(data,1,2)+':'+ copy(data,3,2);
'TX_PWR' : edtPWR.Text := data;
'NAME_INTL','NAME' : if (data<>edtName.Text) and (data<>'') then edtName.Text := data;
'QTH_INTL','QTH' : if (data<>edtQTH.Text) and (data<>'') then edtQTH.Text := data;
'COMMENT_INTL','COMMENT' : if (data<>edtRemQSO.Text) and (data<>'') then edtRemQSO.Text := data;
'IOTA' : if cmbIOTA.Text = '' then cmbIOTA.Text := data;
'STATE' : if edtState.Text='' then edtState.Text := data;
'CQZ' : edtWaz.Text := data;
'ITUZ' : edtITU.Text := data;
'CONTEST_ID': edtContestName.Text := data;
'STX' : edtContestSerialSent.Text := data;
'SRX' : edtContestSerialReceived.Text := data;
//ADIF logger+ definition does not have STXString tag. Added anyway(future?).
'STX_STRING':edtContestExchangeMessageSent.Text := data;
//same with SRX
'SRX_STRING': edtContestExchangeMessageReceived.Text:= data;
'OPERATOR' : Begin
if ((data<>'') and (Op = UpperCase(cqrini.ReadString('Station', 'Call', '')))) then
Begin
Op := data;
sbNewQSO.Panels[2].Text := cOperator+Op;
end;
end;
end; //case
end; //repeat
until pos('<EOR>',uppercase(Buf))=1;
SaveRemote;
buf:=copy(buf,6,length(buf)); //cut eof away.
end; // has tag call
end; //here check if several qsos in block
until Buf = '';
SaveRemote;
end; // has tag call
end; //lasterror=0
end; // while waiting data
end; //if waiting data
tmrN1MM.Enabled:=true;
tmrADIF.Enabled:=true;
end;
procedure TfrmNewQSO.tmrRadioTimer(Sender: TObject);
@ -3088,7 +3149,7 @@ begin
end;
{
The latest UDP message protocol as always is documented in the latest revision of the NetworkMessage.hpp header file:
https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/NetworkMessage.hpp
https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/Network/NetworkMessage.hpp
The reference implementations, particularly message_aggregator, can always be used to verify behaviour or
to construct a recipe to replicate an issue.
@ -4497,12 +4558,12 @@ begin
end
end;
procedure TfrmNewQSO.acRemoteModeN1MMExecute(Sender: TObject);
procedure TfrmNewQSO.acRemoteModeADIFExecute(Sender: TObject);
begin
if mnuRemoteModeN1MM.Checked then
if mnuRemoteModeADIF.Checked then
DisableRemoteMode
else
GoToRemoteMode(n1mm)
GoToRemoteMode(rmtADIF)
end;
procedure TfrmNewQSO.acTuneExecute(Sender : TObject);
@ -7224,7 +7285,7 @@ begin
chkAutoMode.Checked := False;
if mnuRemoteModeWsjt.Checked then //not both on at same time
DisableRemoteMode;
if mnuRemoteModeN1MM.Checked then //not both on at same time
if mnuRemoteModeADIF.Checked then //not both on at same time
DisableRemoteMode;
mnuRemoteMode.Checked := True;
AnyRemoteOn := True;
@ -7242,7 +7303,7 @@ begin
chkAutoMode.Checked := False;
if mnuRemoteMode.Checked then //not both on at same time
DisableRemoteMode;
if mnuRemoteModeN1MM.Checked then //not both on at same time
if mnuRemoteModeADIF.Checked then //not both on at same time
DisableRemoteMode;
mnuRemoteModeWsjt.Checked := True;
AnyRemoteOn := True;
@ -7318,7 +7379,7 @@ begin
if cqrini.ReadBool('Window','MonWsjtx',true) then acMonitorWsjtxExecute(nil)
end;
n1mm : begin
rmtADIF : begin
RememberAutoMode := chkAutoMode.Checked;
chkAutoMode.Checked := False;
if mnuRemoteModeWsjt.Checked then //not both on at same time wsjt
@ -7326,33 +7387,34 @@ begin
if mnuRemoteMode.Checked then //not both on at same time fldigi
DisableRemoteMode;
mnuRemoteModeN1MM.Checked := True;
mnuRemoteModeADIF.Checked := True;
AnyRemoteOn := True;
lblCall.Caption := 'N1MM logger+';
lblCall.Caption := 'remote ADIF';
IsJS8Callrmt := false;
// start UDP server http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket.html
//use lot of wsjtx stuff as it can not be running at same time
N1MMSock := TUDPBlockSocket.Create;
ADIFSock := TUDPBlockSocket.Create;
if dmData.DebugLevel>=1 then Writeln('Socket created!');
N1MMSock.EnableReuse(true);
ADIFSock.EnableReuse(true);
if dmData.DebugLevel>=1 then Writeln('Reuse enabled!');
try
//fix these in preferences
N1MMSock.bind(cqrini.ReadString('n1mm','ip','127.0.0.1'),cqrini.ReadString('n1mm','port','2333'));
ADIFSock.bind(cqrini.ReadString('n1mm','ip','127.0.0.1'),cqrini.ReadString('n1mm','port','2333'));
if dmData.DebugLevel>=1 then Writeln('Bind issued '+cqrini.ReadString('n1mm','ip','127.0.0.1')+
':'+cqrini.ReadString('n1mm','port','2333'));
// On bind failure try to rebind every second
while ((N1MMSock.LastError <> 0) and (tries > 0 )) do
while ((ADIFSock.LastError <> 0) and (tries > 0 )) do
begin
dec(tries);
sleep(1000);
N1MMSock.bind(cqrini.ReadString('n1mm','ip','127.0.0.1'),cqrini.ReadString('n1mm','port','2333'));
ADIFSock.bind(cqrini.ReadString('n1mm','ip','127.0.0.1'),cqrini.ReadString('n1mm','port','2333'));
end;
tmrN1MM.Enabled := True;
tmrADIF.Enabled := True;
except
{if dmData.DebugLevel>=1 then} Writeln('Could not bind socket for N1MM!');
edtRemQSO.Text := 'Could not bind socket for N1MM!';
{if dmData.DebugLevel>=1 then} Writeln('Could not bind socket for ADIF!');
edtRemQSO.Text := 'Could not bind socket for ADIF!';
DisableRemoteMode;
exit
end;
@ -7405,11 +7467,11 @@ begin
AnyRemoteOn := False;
end ;
if mnuRemoteModeN1MM.Checked then
if mnuRemoteModeADIF.Checked then
begin
tmrN1MM.Enabled:=false;
if Assigned(N1MMSock) then FreeAndNil(N1MMSock); // to release UDP socket
mnuRemoteModeN1MM.Checked:= False;
tmrADIF.Enabled:=false;
if Assigned(ADIFSock) then FreeAndNil(ADIFSock); // to release UDP socket
mnuRemoteModeADIF.Checked:= False;
AnyRemoteOn := False;
end;

View File

@ -7500,7 +7500,7 @@ object frmPreferences: TfrmPreferences
object lblwsjtport: TLabel
AnchorSideLeft.Control = edtWsjtPort
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = lbln1mmport
AnchorSideTop.Control = lblADIFport
AnchorSideBottom.Side = asrBottom
Left = 603
Height = 17
@ -7511,9 +7511,9 @@ object frmPreferences: TfrmPreferences
ParentColor = False
end
object edtWsjtPort: TEdit
AnchorSideLeft.Control = edtN1MMPort
AnchorSideLeft.Control = edtADIFPort
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edtN1MMPort
AnchorSideTop.Control = edtADIFPort
AnchorSideRight.Side = asrBottom
Left = 596
Height = 25
@ -7708,7 +7708,7 @@ object frmPreferences: TfrmPreferences
Text = ' . . '
end
end
object edtN1MMPort: TEdit
object edtADIFPort: TEdit
AnchorSideLeft.Control = GroupBox52
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = GroupBox52
@ -7721,7 +7721,7 @@ object frmPreferences: TfrmPreferences
BorderSpacing.Top = 18
TabOrder = 8
end
object lbln1mmport: TLabel
object lblADIFport: TLabel
AnchorSideLeft.Control = GroupBox52
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = GroupBox52
@ -7732,12 +7732,12 @@ object frmPreferences: TfrmPreferences
Width = 83
BorderSpacing.Left = 12
BorderSpacing.Bottom = 35
Caption = 'N1MM port:'
Caption = 'ADIF port:'
ParentColor = False
end
object edtn1mmIp: TEdit
AnchorSideLeft.Control = edtN1MMPort
AnchorSideTop.Control = lbln1mmaddr
object edtADIFIp: TEdit
AnchorSideLeft.Control = edtADIFPort
AnchorSideTop.Control = lblADIFaddr
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 500
@ -7747,17 +7747,17 @@ object frmPreferences: TfrmPreferences
BorderSpacing.Top = 2
TabOrder = 9
end
object lbln1mmaddr: TLabel
AnchorSideLeft.Control = edtn1mmIp
object lblADIFaddr: TLabel
AnchorSideLeft.Control = edtADIFIp
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = edtN1MMPort
AnchorSideTop.Control = edtADIFPort
AnchorSideTop.Side = asrBottom
Left = 498
Height = 17
Top = 51
Width = 84
BorderSpacing.Top = 2
Caption = 'N1MM addr:'
Caption = 'ADIF addr:'
ParentColor = False
end
end

View File

@ -600,11 +600,11 @@ type
edtK3NGPort1: TEdit;
edtK3NGSpeed: TSpinEdit;
edtFldigiIp: TEdit;
edtn1mmIp: TEdit;
edtADIFIp: TEdit;
edtWsjtPath: TEdit;
edtWsjtPort: TEdit;
edtFldigiPort: TEdit;
edtN1MMPort: TEdit;
edtADIFPort: TEdit;
edtXRefresh: TEdit;
edtXLastSpots: TEdit;
edtXTop: TEdit;
@ -831,8 +831,8 @@ type
lblHamLibSpeed: TLabel;
lblHamLibWPM: TLabel;
Label202: TLabel;
lbln1mmport: TLabel;
lbln1mmaddr: TLabel;
lblADIFport: TLabel;
lblADIFaddr: TLabel;
lblWinPort2: TLabel;
lblwsjtport: TLabel;
Label204: TLabel;
@ -1561,8 +1561,8 @@ begin
cqrini.WriteBool('wsjt','wb4CCall', cgLimit.Checked[0]);
cqrini.WriteBool('wsjt','wb4CLoc', cgLimit.Checked[1]);
cqrini.WriteString('n1mm','port',edtn1mmPort.Text);
cqrini.WriteString('n1mm','ip',edtn1mmIp.Text);
cqrini.WriteString('n1mm','port',edtADIFPort.Text);
cqrini.WriteString('n1mm','ip',edtADIFIp.Text);
if edtBackupPath.Text <> '' then
if edtBackupPath.Text[Length(edtBackupPath.Text)] <> PathDelim then
@ -1797,7 +1797,7 @@ var
'h1.html#bh3', //zip code tracking
'h1.html#bh4', //lotw support
'h1.html#ch1', //cw interface
'h1.html#ch2', //fldigi wsjt-x n1mm interface
'h1.html#ch2', //fldigi wsjt-x ADIF interface
'h1.html#ch3', //autobackup
'h1.html#ch4', //external viewers
'h1.html#ch5', //callbook support
@ -3083,8 +3083,8 @@ begin
cgLimit.Checked[0] := cqrini.ReadBool('wsjt','wb4CCall', False);
cgLimit.Checked[1] := cqrini.ReadBool('wsjt','wb4CLoc', False);
edtn1mmPort.Text := cqrini.ReadString('n1mm','port','2333');
edtn1mmIp.Text := cqrini.ReadString('n1mm','ip','127.0.0.1');
edtADIFPort.Text := cqrini.ReadString('n1mm','port','2333');
edtADIFIp.Text := cqrini.ReadString('n1mm','ip','127.0.0.1');
chkEnableBackup.Checked := cqrini.ReadBool('Backup', 'Enable', False);