Message unpacking fixes and improved test coverage

Fix packjt truncation error and text3 null detection.

Add additional test messages.

Add  check  message  capability  to   jt65code  and  jt9code  so  that
comparison confirms expected output.

jt65code and jt9code now  should always have identical outputs..should
allow for automatic regression testing.

Thanks to Mike, W9MDB, for this contribution.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7649 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2017-04-22 12:40:44 +00:00
parent 4e3fdfef9e
commit 52fedc02c5
4 changed files with 338 additions and 170 deletions

View File

@ -1,85 +1,101 @@
program JT65code program JT65code
! Provides examples of message packing, bit and symbol ordering, ! Provides examples of message packing, bit and symbol ordering,
! Reed Solomon encoding, and other necessary details of the JT65 ! Reed Solomon encoding, and other necessary details of the JT65
! protocol. ! protocol.
use packjt use packjt
character*22 msg,msg0,msg1,decoded,cok*3,bad*1,msgtype*10 character*22 msg,msgchk,msg0,msg1,decoded,cok*3,bad*1,msgtype*10,expected
integer dgen(12),sent(63),tmp(63),recd(12),era(51) integer dgen(12),sent(63),tmp(63),recd(12),era(51)
include 'testmsg.f90' include 'testmsg.f90'
nargs=iargc() nargs=iargc()
if(nargs.ne.1) then if(nargs.ne.1) then
print*,'Usage: jt65code "message"' print*,'Usage: jt65code "message"'
print*,' jt65code -t' print*,' jt65code -t'
go to 999 go to 999
endif endif
call getarg(1,msg) !Get message from command line call getarg(1,msg) !Get message from command line
nmsg=1 msgchk=msg
if(msg(1:2).eq."-t") then call fmtmsg(msgchk,iz)
testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO" nmsg=1
testmsg(NTEST+2)="KA1ABC WB9XYZ OOO" if(msg(1:2).eq."-t") then
testmsg(NTEST+3)="RO" if (NTEST+5 > MAXTEST) then
testmsg(NTEST+4)="RRR" write(*,*) "NTEST exceed MAXTEST"
testmsg(NTEST+5)="73" endif
nmsg=NTEST+5 testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
endif testmsg(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsg(NTEST+3)="RO"
write(*,1010) testmsg(NTEST+4)="RRR"
1010 format(" Message Decoded Err? Type"/ & testmsg(NTEST+5)="73"
74("-")) testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO"
do imsg=1,nmsg testmsgchk(NTEST+3)="RO"
if(nmsg.gt.1) msg=testmsg(imsg) testmsgchk(NTEST+4)="RRR"
testmsgchk(NTEST+5)="73"
call fmtmsg(msg,iz) !To upper, collapse mult blanks nmsg=NTEST+5
msg0=msg !Input message endif
call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report
msg1=msg !Message without "OOO" write(*,1010)
1010 format(" Message Decoded Err? Type Expected"/ &
if(nspecial.gt.0) then !or is a shorthand message 76("-"))
if(nspecial.eq.2) decoded="RO"
if(nspecial.eq.3) decoded="RRR" do imsg=1,nmsg
if(nspecial.eq.4) decoded="73" if(nmsg.gt.1) then
itype=-1 msg=testmsg(imsg)
msgtype="Shorthand" msgchk=testmsgchk(imsg)
go to 10 endif
endif
call fmtmsg(msg,iz) !To upper, collapse mult blanks
call packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes msg0=msg !Input message
msgtype="" call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report
if(itype.eq.1) msgtype="Std Msg" msg1=msg !Message without "OOO"
if(itype.eq.2) msgtype="Type 1 pfx"
if(itype.eq.3) msgtype="Type 1 sfx" if(nspecial.gt.0) then !or is a shorthand message
if(itype.eq.4) msgtype="Type 2 pfx" if(nspecial.eq.2) decoded="RO"
if(itype.eq.5) msgtype="Type 2 sfx" if(nspecial.eq.3) decoded="RRR"
if(itype.eq.6) msgtype="Free text" if(nspecial.eq.4) decoded="73"
itype=-1
call rs_encode(dgen,sent) !RS encode msgtype="Shorthand"
call interleave63(sent,1) !Interleave channel symbols go to 10
call graycode(sent,63,1,sent) !Apply Gray code endif
call graycode(sent,63,-1,tmp) !Remove Gray code call packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes
call interleave63(tmp,-1) !Remove interleaving msgtype=""
call rs_decode(tmp,era,0,recd,nerr) !Decode the message if(itype.eq.1) msgtype="Std Msg"
call unpackmsg(recd,decoded) !Unpack the user message if(itype.eq.2) msgtype="Type 1 pfx"
if(cok.eq."OOO") decoded(20:22)=cok if(itype.eq.3) msgtype="Type 1 sfx"
call fmtmsg(decoded,iz) if(itype.eq.4) msgtype="Type 2 pfx"
if(itype.eq.5) msgtype="Type 2 sfx"
10 bad=" " if(itype.eq.6) msgtype="Free text"
if(decoded.ne.msg0) bad="*"
write(*,1020) imsg,msg0,decoded,bad,itype,msgtype call rs_encode(dgen,sent) !RS encode
1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13) call interleave63(sent,1) !Interleave channel symbols
enddo call graycode(sent,63,1,sent) !Apply Gray code
if(nmsg.eq.1 .and. nspecial.eq.0) then call graycode(sent,63,-1,tmp) !Remove Gray code
write(*,1030) dgen call interleave63(tmp,-1) !Remove interleaving
1030 format(/'Packed message, 6-bit symbols ',12i3) !Display packed symbols call rs_decode(tmp,era,0,recd,nerr) !Decode the message
call unpackmsg(recd,decoded) !Unpack the user message
write(*,1040) sent if(cok.eq."OOO") decoded(20:22)=cok
1040 format(/'Information-carrying channel symbols'/(i5,20i3)) call fmtmsg(decoded,iz)
endif
10 bad=" "
999 end program JT65code if(decoded.ne.msgchk) bad="*"
expected = 'EXACT'
if (msg0.ne.msgchk) expected = 'TRUNCATED'
if (nmsg.eq.1) expected = 'UNKNOWN'
write(*,1020) imsg,msg0,decoded,bad,itype,msgtype,expected
1020 format(i2,'.',1x,a22,1x,a22,1x,a1,i3,":",a10,2x,a22)
enddo
if(nmsg.eq.1 .and. nspecial.eq.0) then
write(*,1030) dgen
1030 format(/'Packed message, 6-bit symbols ',12i3) !Display packed symbols
write(*,1040) sent
1040 format(/'Information-carrying channel symbols'/(i5,20i3))
endif
999 end program JT65code

View File

@ -1,47 +1,84 @@
program jt9code program jt9code
! Generate simulated data for testing of WSJT-X ! Generate simulated data for testing of WSJT-X
character msg*22,decoded*22,bad*1,msgtype*13 character*22 msg,msgchk,msg0,msg1,decoded,cok*3,bad*1,msgtype*10,expected
integer*4 i4tone(85) !Channel symbols (values 0-8) integer*4 i4tone(85) !Channel symbols (values 0-8)
include 'testmsg.f90' include 'testmsg.f90'
include 'jt9sync.f90' include 'jt9sync.f90'
nargs=iargc() nargs=iargc()
if(nargs.ne.1) then if(nargs.ne.1) then
print*,'Usage: jt9code "message"' print*,'Usage: jt9code "message"'
print*,' jt9code -t' print*,' jt9code -t'
go to 999 go to 999
endif endif
call getarg(1,msg) call getarg(1,msg)
nmsg=1 nmsg=1
if(msg(1:2).eq."-t") nmsg=NTEST if(msg(1:2).eq."-t") then
if (NTEST+5 > MAXTEST) then
write(*,1010) write(*,*) "NTEST exceed MAXTEST"
1010 format(" Message Decoded Err? Type"/ & endif
74("-")) testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
do imsg=1,nmsg testmsg(NTEST+2)="KA1ABC WB9XYZ OOO"
if(nmsg.gt.1) msg=testmsg(imsg) testmsg(NTEST+3)="RO"
call fmtmsg(msg,iz) !To upper case, collapse multiple blanks testmsg(NTEST+4)="RRR"
ichk=0 testmsg(NTEST+5)="73"
call gen9(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO"
msgtype="" testmsgchk(NTEST+3)="RO"
if(itype.eq.1) msgtype="Std Msg" testmsgchk(NTEST+4)="RRR"
if(itype.eq.2) msgtype="Type 1 prefix" testmsgchk(NTEST+5)="73"
if(itype.eq.3) msgtype="Type 1 suffix" nmsg=NTEST+5
if(itype.eq.4) msgtype="Type 2 prefix" endif
if(itype.eq.5) msgtype="Type 2 suffix"
if(itype.eq.6) msgtype="Free text" write(*,1010)
1010 format(" Message Decoded Err? Type Expected"/ &
bad=" " 76("-"))
if(decoded.ne.msg) bad="*" do imsg=1,nmsg
write(*,1020) imsg,msg,decoded,bad,itype,msgtype if(nmsg.gt.1) then
1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13) msg=testmsg(imsg)
enddo msgchk=testmsgchk(imsg)
endif
if(nmsg.eq.1) write(*,1030) i4tone call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
1030 format(/'Channel symbols'/(30i2)) msg0=msg
ichk=0
999 end program jt9code call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report
msg1=msg !Message without "OOO"
if(nspecial.gt.0) then !or is a shorthand message
if(nspecial.eq.2) decoded="RO"
if(nspecial.eq.3) decoded="RRR"
if(nspecial.eq.4) decoded="73"
itype=-1
msgtype="Shorthand"
go to 10
endif
call gen9(msg,ichk,decoded,i4tone,itype) !Encode message into tone #s
msgtype=""
if(itype.eq.1) msgtype="Std Msg"
if(itype.eq.2) msgtype="Type 1 pfx"
if(itype.eq.3) msgtype="Type 1 sfx"
if(itype.eq.4) msgtype="Type 2 pfx"
if(itype.eq.5) msgtype="Type 2 sfx"
if(itype.eq.6) msgtype="Free text"
if(cok.eq."OOO") decoded(20:22)=cok
call fmtmsg(decoded,iz)
10 bad=" "
expected = 'EXACT'
if (msg0.ne.msgchk) expected = 'TRUNCATED'
if (nmsg.eq.1) expected = 'UNKNOWN'
if(decoded.ne.msgchk) bad="*"
write(*,1020) imsg,msg0,decoded,bad,itype,msgtype,expected
1020 format(i2,'.',1x,a22,1x,a22,1x,a1,i3,":",a10,2x,a22)
enddo
if(nmsg.eq.1) write(*,1030) i4tone
1030 format(/'Channel symbols'/(30i2))
999 end program jt9code

View File

@ -416,7 +416,7 @@ subroutine packbits(dbits,nsymd,m0,sym)
call fmtmsg(msg,iz) call fmtmsg(msg,iz)
if(msg(1:6).eq.'CQ DX ') msg(3:3)='9' if(msg(1:6).eq.'CQ DX ') msg(3:3)='9'
if(msg(1:3).eq."CQ " .and. & if(msg(1:3).eq.'CQ ' .and. &
msg(4:4).ge.'A' .and. msg(4:4).le.'Z' .and. & msg(4:4).ge.'A' .and. msg(4:4).le.'Z' .and. &
msg(5:5).ge.'A' .and. msg(5:5).le.'Z' .and. & msg(5:5).ge.'A' .and. msg(5:5).le.'Z' .and. &
msg(6:6).eq.' ') msg='E9'//msg(4:) msg(6:6).eq.' ') msg='E9'//msg(4:)
@ -478,13 +478,13 @@ subroutine packbits(dbits,nsymd,m0,sym)
nc1=0 nc1=0
if(nv2b.eq.4) then if(nv2b.eq.4) then
if(c1(1:3).eq.'CQ ') nc1=262178563 + k2 if(c1(1:3).eq.'CQ ' .and. (.not.text3)) nc1=262178563 + k2
if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2 if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=264002072 + k2
if(c1(1:3).eq.'DE ') nc1=265825581 + k2 if(c1(1:3).eq.'DE ' .and. (.not.text3)) nc1=265825581 + k2
else if(nv2b.eq.5) then else if(nv2b.eq.5) then
if(c1(1:3).eq.'CQ ') nc1=267649090 + k2 if(c1(1:3).eq.'CQ ' .and. (.not.text3)) nc1=267649090 + k2
if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2 if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=267698375 + k2
if(c1(1:3).eq.'DE ') nc1=267747660 + k2 if(c1(1:3).eq.'DE ' .and. (.not.text3)) nc1=267747660 + k2
endif endif
if(nc1.ne.0) go to 20 if(nc1.ne.0) go to 20
@ -638,7 +638,7 @@ subroutine packbits(dbits,nsymd,m0,sym)
subroutine packtext(msg,nc1,nc2,nc3) subroutine packtext(msg,nc1,nc2,nc3)
parameter (MASK28=2**28 - 1) parameter (MASK28=2**28 - 1)
character*13 msg character*22 msg
character*42 c character*42 c
data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/ data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/

View File

@ -1,30 +1,145 @@
parameter (MAXTEST=35,NTEST=27) parameter (MAXTEST=75,NTEST=68)
character*22 testmsg(MAXTEST) character*22 testmsg(MAXTEST)
data testmsg(1:NTEST)/ & character*22 testmsgchk(MAXTEST)
"CQ WB9XYZ EN34", & ! Test msgs should include the extremes for the different types
"CQ DX WB9XYZ EN34", & ! See pfx.f90
"QRZ WB9XYZ EN34", & ! Type 1 P & A
"KA1ABC WB9XYZ EN34", & ! Type 1 1A & E5
"KA1ABC WB9XYZ RO", & data testmsg(1:NTEST)/ &
"KA1ABC WB9XYZ -21", & "CQ WB9XYZ EN34", &
"KA1ABC WB9XYZ R-19", & "CQ DX WB9XYZ EN34", &
"KA1ABC WB9XYZ RRR", & "QRZ WB9XYZ EN34", &
"KA1ABC WB9XYZ 73", & "KA1ABC WB9XYZ EN34", &
"KA1ABC WB9XYZ", & "KA1ABC WB9XYZ RO", &
"CQ 000 WB9XYZ EN34", & "KA1ABC WB9XYZ -21", &
"CQ 999 WB9XYZ EN34", & "KA1ABC WB9XYZ R-19", &
"CQ EU WB9XYZ EN34", & "KA1ABC WB9XYZ RRR", &
"CQ WY WB9XYZ EN34", & "KA1ABC WB9XYZ 73", &
"ZL/KA1ABC WB9XYZ", & "KA1ABC WB9XYZ", &
"KA1ABC ZL/WB9XYZ", & "CQ 000 WB9XYZ EN34", &
"KA1ABC/4 WB9XYZ", & "CQ 999 WB9XYZ EN34", &
"KA1ABC WB9XYZ/4", & "CQ EU WB9XYZ EN34", &
"CQ ZL4/KA1ABC", & "CQ WY WB9XYZ EN34", &
"DE ZL4/KA1ABC", & "1A/KA1ABC WB9XYZ", &
"QRZ ZL4/KA1ABC", & "E5/KA1ABC WB9XYZ", &
"CQ WB9XYZ/VE4", & "KA1ABC 1A/WB9XYZ", &
"HELLO WORLD", & "KA1ABC E5/WB9XYZ", &
"ZL4/KA1ABC 73", & "KA1ABC/P WB9XYZ", &
"KA1ABC XL/WB9XYZ", & "KA1ABC/A WB9XYZ", &
"KA1ABC WB9XYZ/W4", & "KA1ABC WB9XYZ/P", &
"123456789ABCDEFGH"/ "KA1ABC WB9XYZ/A", &
"CQ KA1ABC/P", &
"CQ WB9XYZ/A", &
"QRZ KA1ABC/P", &
"QRZ WB9XYZ/A", &
"DE KA1ABC/P", &
"DE WB9XYZ/A", &
"CQ 1A/KA1ABC", &
"CQ E5/KA1ABC", &
"DE 1A/KA1ABC", &
"DE E5/KA1ABC", &
"QRZ 1A/KA1ABC", &
"QRZ E5/KA1ABC", &
"CQ WB9XYZ/1A", &
"CQ WB9XYZ/E5", &
"QRZ WB9XYZ/1A", &
"QRZ WB9XYZ/E5", &
"DE WB9XYZ/1A", &
"DE WB9XYZ/E5", &
"CQ A000/KA1ABC FM07", &
"CQ ZZZZ/KA1ABC FM07", &
"QRZ W4/KA1ABC FM07", &
"DE W4/KA1ABC FM07", &
"CQ W4/KA1ABC -22", &
"DE W4/KA1ABC -22", &
"QRZ W4/KA1ABC -22", &
"CQ W4/KA1ABC R-22", &
"DE W4/KA1ABC R-22", &
"QRZ W4/KA1ABC R-22", &
"DE W4/KA1ABC 73", &
"CQ KA1ABC FM07", &
"QRZ KA1ABC FM07", &
"DE KA1ABC/VE6 FM07", &
"CQ KA1ABC/VE6 -22", &
"DE KA1ABC/VE6 -22", &
"QRZ KA1ABC/VE6 -22", &
"CQ KA1ABC/VE6 R-22", &
"DE KA1ABC/VE6 R-22", &
"QRZ KA1ABC/VE6 R-22", &
"DE KA1ABC 73", &
"HELLO WORLD", &
"ZL4/KA1ABC 73", &
"KA1ABC XL/WB9XYZ", &
"KA1ABC WB9XYZ/W4", &
"DE KA1ABC/QRP 2W", &
"KA1ABC/1 WB9XYZ/1", &
"123456789ABCDEFGH"/
data testmsgchk(1:NTEST)/ &
"CQ WB9XYZ EN34", &
"CQ DX WB9XYZ EN34", &
"QRZ WB9XYZ EN34", &
"KA1ABC WB9XYZ EN34", &
"KA1ABC WB9XYZ RO", &
"KA1ABC WB9XYZ -21", &
"KA1ABC WB9XYZ R-19", &
"KA1ABC WB9XYZ RRR", &
"KA1ABC WB9XYZ 73", &
"KA1ABC WB9XYZ", &
"CQ 000 WB9XYZ EN34", &
"CQ 999 WB9XYZ EN34", &
"CQ EU WB9XYZ EN34", &
"CQ WY WB9XYZ EN34", &
"1A/KA1ABC WB9XYZ", &
"E5/KA1ABC WB9XYZ", &
"KA1ABC 1A/WB9XYZ", &
"KA1ABC E5/WB9XYZ", &
"KA1ABC/P WB9XYZ", &
"KA1ABC/A WB9XYZ", &
"KA1ABC WB9XYZ/P", &
"KA1ABC WB9XYZ/A", &
"CQ KA1ABC/P", &
"CQ WB9XYZ/A", &
"QRZ KA1ABC/P", &
"QRZ WB9XYZ/A", &
"DE KA1ABC/P", &
"DE WB9XYZ/A", &
"CQ 1A/KA1ABC", &
"CQ E5/KA1ABC", &
"DE 1A/KA1ABC", &
"DE E5/KA1ABC", &
"QRZ 1A/KA1ABC", &
"QRZ E5/KA1ABC", &
"CQ WB9XYZ/1A", &
"CQ WB9XYZ/E5", &
"QRZ WB9XYZ/1A", &
"QRZ WB9XYZ/E5", &
"DE WB9XYZ/1A", &
"DE WB9XYZ/E5", &
"CQ A000/KA1ABC FM07", &
"CQ ZZZZ/KA1ABC FM07", &
"QRZ W4/KA1ABC FM07", &
"DE W4/KA1ABC FM07", &
"CQ W4/KA1ABC -22", &
"DE W4/KA1ABC -22", &
"QRZ W4/KA1ABC -22", &
"CQ W4/KA1ABC R-22", &
"DE W4/KA1ABC R-22", &
"QRZ W4/KA1ABC R-22", &
"DE W4/KA1ABC 73", &
"CQ KA1ABC FM07", &
"QRZ KA1ABC FM07", &
"DE KA1ABC/VE6 FM07", &
"CQ KA1ABC/VE6 -22", &
"DE KA1ABC/VE6 -22", &
"QRZ KA1ABC/VE6 -22", &
"CQ KA1ABC/VE6 R-22", &
"DE KA1ABC/VE6 R-22", &
"QRZ KA1ABC/VE6 R-22", &
"DE KA1ABC 73", &
"HELLO WORLD", &
"ZL4/KA1ABC 73", &
"KA1ABC XL/WB9", &
"KA1ABC WB9XYZ", &
"DE KA1ABC/QRP", &
"KA1ABC/1 WB9X", &
"123456789ABCD"/