program dmr_protocol_test; {$MODE Delphi} uses SysUtils, DMRProtocol; const CACH_INTERLEAVE: array[0..23] of Byte = ( 0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23 ); procedure PutCACH(var Burst: TDMRDibitBurst; Value: Byte); var Code: TDMRBit7; Deinterleaved, Transmitted: array[0..23] of Byte; i: Integer; begin FillChar(Deinterleaved, SizeOf(Deinterleaved), 0); Code := DMRHamming74Encode(Value); for i := 0 to 6 do Deinterleaved[i] := Code[i]; for i := 0 to 23 do Transmitted[i] := Deinterleaved[CACH_INTERLEAVE[i]]; for i := 0 to 11 do Burst[i] := (Transmitted[2 * i] shl 1) or Transmitted[2 * i + 1]; end; procedure PutSlotType(var Burst: TDMRDibitBurst; Value: Byte); var Code: TDMRBit20; i, k: Integer; begin Code := DMRGolay208Encode(Value); k := 0; for i := 61 to 65 do begin Burst[i] := (Code[k] shl 1) or Code[k + 1]; Inc(k, 2); end; for i := 90 to 94 do begin Burst[i] := (Code[k] shl 1) or Code[k + 1]; Inc(k, 2); end; end; procedure Check(Condition: Boolean; const Message_: string); begin if not Condition then begin WriteLn(Message_); Halt(1); end; end; var Burst: TDMRDibitBurst; Info: TDMRBurstInfo; begin FillChar(Burst, SizeOf(Burst), 0); // TACT: AT=1, slot=1 (TS2), LCSS=2. Slot Type: CC=9, data header=6. PutCACH(Burst, $0E); PutSlotType(Burst, $96); DMRParseBurst(Burst, Info); Check(Info.CACH.Valid, 'valid CACH rejected'); Check(Info.CACH.AccessType and (Info.CACH.Slot = 1) and (Info.CACH.LCSS = 2), 'TACT fields decoded incorrectly'); Check(Info.SlotType.Valid, 'valid Slot Type rejected'); Check((Info.SlotType.ColorCode = 9) and (Info.SlotType.DataType = 6), 'Slot Type fields decoded incorrectly'); // Hamming(7,4) corrects one bit and Golay(20,8) corrects two. Burst[0] := Burst[0] xor 2; Burst[61] := Burst[61] xor 2; Burst[92] := Burst[92] xor 1; DMRParseBurst(Burst, Info); Check(Info.CACH.Valid and (Info.CACH.CorrectedBits = 1), 'CACH one-bit correction failed'); Check(Info.CACH.AccessType and (Info.CACH.Slot = 1) and (Info.CACH.LCSS = 2), 'corrected TACT fields are wrong'); Check(Info.SlotType.Valid and (Info.SlotType.CorrectedBits = 2), 'Slot Type two-bit correction failed'); Check((Info.SlotType.ColorCode = 9) and (Info.SlotType.DataType = 6), 'corrected Slot Type fields are wrong'); // A third Slot Type error exceeds the guaranteed correction radius. Burst[94] := Burst[94] xor 1; DMRParseBurst(Burst, Info); Check(not Info.SlotType.Valid, 'uncorrectable Slot Type accepted'); WriteLn('DMR CACH and Slot Type tests passed'); end.