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
! Provides examples of message packing, bit and symbol ordering,
! Reed Solomon encoding, and other necessary details of the JT65
! protocol.
use packjt
character*22 msg,msg0,msg1,decoded,cok*3,bad*1,msgtype*10
integer dgen(12),sent(63),tmp(63),recd(12),era(51)
include 'testmsg.f90'
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: jt65code "message"'
print*,' jt65code -t'
go to 999
endif
call getarg(1,msg) !Get message from command line
nmsg=1
if(msg(1:2).eq."-t") then
testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsg(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsg(NTEST+3)="RO"
testmsg(NTEST+4)="RRR"
testmsg(NTEST+5)="73"
nmsg=NTEST+5
endif
write(*,1010)
1010 format(" Message Decoded Err? Type"/ &
74("-"))
do imsg=1,nmsg
if(nmsg.gt.1) msg=testmsg(imsg)
call fmtmsg(msg,iz) !To upper, collapse mult blanks
msg0=msg !Input message
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 packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes
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"
call rs_encode(dgen,sent) !RS encode
call interleave63(sent,1) !Interleave channel symbols
call graycode(sent,63,1,sent) !Apply Gray code
call graycode(sent,63,-1,tmp) !Remove Gray code
call interleave63(tmp,-1) !Remove interleaving
call rs_decode(tmp,era,0,recd,nerr) !Decode the message
call unpackmsg(recd,decoded) !Unpack the user message
if(cok.eq."OOO") decoded(20:22)=cok
call fmtmsg(decoded,iz)
10 bad=" "
if(decoded.ne.msg0) bad="*"
write(*,1020) imsg,msg0,decoded,bad,itype,msgtype
1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13)
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
program JT65code
! Provides examples of message packing, bit and symbol ordering,
! Reed Solomon encoding, and other necessary details of the JT65
! protocol.
use packjt
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)
include 'testmsg.f90'
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: jt65code "message"'
print*,' jt65code -t'
go to 999
endif
call getarg(1,msg) !Get message from command line
msgchk=msg
call fmtmsg(msgchk,iz)
nmsg=1
if(msg(1:2).eq."-t") then
if (NTEST+5 > MAXTEST) then
write(*,*) "NTEST exceed MAXTEST"
endif
testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsg(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsg(NTEST+3)="RO"
testmsg(NTEST+4)="RRR"
testmsg(NTEST+5)="73"
testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsgchk(NTEST+3)="RO"
testmsgchk(NTEST+4)="RRR"
testmsgchk(NTEST+5)="73"
nmsg=NTEST+5
endif
write(*,1010)
1010 format(" Message Decoded Err? Type Expected"/ &
76("-"))
do imsg=1,nmsg
if(nmsg.gt.1) then
msg=testmsg(imsg)
msgchk=testmsgchk(imsg)
endif
call fmtmsg(msg,iz) !To upper, collapse mult blanks
msg0=msg !Input message
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 packmsg(msg1,dgen,itype) !Pack message into 12 six-bit bytes
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"
call rs_encode(dgen,sent) !RS encode
call interleave63(sent,1) !Interleave channel symbols
call graycode(sent,63,1,sent) !Apply Gray code
call graycode(sent,63,-1,tmp) !Remove Gray code
call interleave63(tmp,-1) !Remove interleaving
call rs_decode(tmp,era,0,recd,nerr) !Decode the message
call unpackmsg(recd,decoded) !Unpack the user message
if(cok.eq."OOO") decoded(20:22)=cok
call fmtmsg(decoded,iz)
10 bad=" "
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
! Generate simulated data for testing of WSJT-X
character msg*22,decoded*22,bad*1,msgtype*13
integer*4 i4tone(85) !Channel symbols (values 0-8)
include 'testmsg.f90'
include 'jt9sync.f90'
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: jt9code "message"'
print*,' jt9code -t'
go to 999
endif
call getarg(1,msg)
nmsg=1
if(msg(1:2).eq."-t") nmsg=NTEST
write(*,1010)
1010 format(" Message Decoded Err? Type"/ &
74("-"))
do imsg=1,nmsg
if(nmsg.gt.1) msg=testmsg(imsg)
call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
ichk=0
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 prefix"
if(itype.eq.3) msgtype="Type 1 suffix"
if(itype.eq.4) msgtype="Type 2 prefix"
if(itype.eq.5) msgtype="Type 2 suffix"
if(itype.eq.6) msgtype="Free text"
bad=" "
if(decoded.ne.msg) bad="*"
write(*,1020) imsg,msg,decoded,bad,itype,msgtype
1020 format(i2,'.',2x,a22,2x,a22,3x,a1,i3,": ",a13)
enddo
if(nmsg.eq.1) write(*,1030) i4tone
1030 format(/'Channel symbols'/(30i2))
999 end program jt9code
program jt9code
! Generate simulated data for testing of WSJT-X
character*22 msg,msgchk,msg0,msg1,decoded,cok*3,bad*1,msgtype*10,expected
integer*4 i4tone(85) !Channel symbols (values 0-8)
include 'testmsg.f90'
include 'jt9sync.f90'
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: jt9code "message"'
print*,' jt9code -t'
go to 999
endif
call getarg(1,msg)
nmsg=1
if(msg(1:2).eq."-t") then
if (NTEST+5 > MAXTEST) then
write(*,*) "NTEST exceed MAXTEST"
endif
testmsg(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsg(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsg(NTEST+3)="RO"
testmsg(NTEST+4)="RRR"
testmsg(NTEST+5)="73"
testmsgchk(NTEST+1)="KA1ABC WB9XYZ EN34 OOO"
testmsgchk(NTEST+2)="KA1ABC WB9XYZ OOO"
testmsgchk(NTEST+3)="RO"
testmsgchk(NTEST+4)="RRR"
testmsgchk(NTEST+5)="73"
nmsg=NTEST+5
endif
write(*,1010)
1010 format(" Message Decoded Err? Type Expected"/ &
76("-"))
do imsg=1,nmsg
if(nmsg.gt.1) then
msg=testmsg(imsg)
msgchk=testmsgchk(imsg)
endif
call fmtmsg(msg,iz) !To upper case, collapse multiple blanks
msg0=msg
ichk=0
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)
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(5:5).ge.'A' .and. msg(5:5).le.'Z' .and. &
msg(6:6).eq.' ') msg='E9'//msg(4:)
@ -478,13 +478,13 @@ subroutine packbits(dbits,nsymd,m0,sym)
nc1=0
if(nv2b.eq.4) then
if(c1(1:3).eq.'CQ ') nc1=262178563 + k2
if(c1(1:4).eq.'QRZ ') nc1=264002072 + k2
if(c1(1:3).eq.'DE ') nc1=265825581 + k2
if(c1(1:3).eq.'CQ ' .and. (.not.text3)) nc1=262178563 + k2
if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=264002072 + k2
if(c1(1:3).eq.'DE ' .and. (.not.text3)) nc1=265825581 + k2
else if(nv2b.eq.5) then
if(c1(1:3).eq.'CQ ') nc1=267649090 + k2
if(c1(1:4).eq.'QRZ ') nc1=267698375 + k2
if(c1(1:3).eq.'DE ') nc1=267747660 + k2
if(c1(1:3).eq.'CQ ' .and. (.not.text3)) nc1=267649090 + k2
if(c1(1:4).eq.'QRZ ' .and. (.not.text3)) nc1=267698375 + k2
if(c1(1:3).eq.'DE ' .and. (.not.text3)) nc1=267747660 + k2
endif
if(nc1.ne.0) go to 20
@ -638,7 +638,7 @@ subroutine packbits(dbits,nsymd,m0,sym)
subroutine packtext(msg,nc1,nc2,nc3)
parameter (MASK28=2**28 - 1)
character*13 msg
character*22 msg
character*42 c
data c/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-./?'/

View File

@ -1,30 +1,145 @@
parameter (MAXTEST=35,NTEST=27)
character*22 testmsg(MAXTEST)
data testmsg(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", &
"ZL/KA1ABC WB9XYZ", &
"KA1ABC ZL/WB9XYZ", &
"KA1ABC/4 WB9XYZ", &
"KA1ABC WB9XYZ/4", &
"CQ ZL4/KA1ABC", &
"DE ZL4/KA1ABC", &
"QRZ ZL4/KA1ABC", &
"CQ WB9XYZ/VE4", &
"HELLO WORLD", &
"ZL4/KA1ABC 73", &
"KA1ABC XL/WB9XYZ", &
"KA1ABC WB9XYZ/W4", &
"123456789ABCDEFGH"/
parameter (MAXTEST=75,NTEST=68)
character*22 testmsg(MAXTEST)
character*22 testmsgchk(MAXTEST)
! Test msgs should include the extremes for the different types
! See pfx.f90
! Type 1 P & A
! Type 1 1A & E5
data testmsg(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/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"/