diff --git a/src/decode/p25/P25Interleave.java b/src/decode/p25/P25Interleave.java index 9d80d6fb..3e896185 100644 --- a/src/decode/p25/P25Interleave.java +++ b/src/decode/p25/P25Interleave.java @@ -97,27 +97,31 @@ public class P25Interleave public static void main( String[] args ) { + TrellisHalfRate halfrate = new TrellisHalfRate(); + int start = 0; int end = 196; - + String interleaved = "1000100100100011001000100010110010001000100010010000100010011100100101001000001000100010001011000110010001111011110010001000100010001000100010000011011100101011001000101000100010001000100010110101"; + BitSetBuffer b = new BitSetBuffer( end ); - for( int x = 0; x < end; x += 3 ) + for( int x = 0; x < end; x++ ) { - if( x > 20 ) + if( interleaved.substring( x, x + 1 ).contentEquals( "1" ) ) { - b.set( x ); + b.set( x ); } } - - mLog.debug( "Origi:" + b.toString() ); - - P25Interleave.interleave( b, start, end ); - - mLog.debug( "Inter:" + b.toString() ); + mLog.debug( "Interleaved:" + interleaved ); + mLog.debug( " Buffer:" + b.toString() ); + P25Interleave.deinterleave( b, start, end ); - mLog.debug( "Donee:" + b.toString() ); + mLog.debug( "Deinterleav:" + b.toString() ); + + halfrate.decode( b, start, end ); + + mLog.debug( "Trellis Off:" + b.toString() ); } } diff --git a/src/decode/p25/P25MessageProcessor.java b/src/decode/p25/P25MessageProcessor.java index 40ad6764..993fce9c 100644 --- a/src/decode/p25/P25MessageProcessor.java +++ b/src/decode/p25/P25MessageProcessor.java @@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory; import sample.Listener; import alias.AliasList; +import decode.p25.message.tsbk.TSBKMessage; public class P25MessageProcessor implements Listener { @@ -23,6 +24,13 @@ public class P25MessageProcessor implements Listener @Override public void receive( Message message ) { - mLog.debug( "P25: " + message.toString() + "\t" + message.getBinaryMessage() ); + if( message instanceof TSBKMessage ) + { + mLog.debug( message.getMessage() ); + } + else + { + mLog.debug( message.getMessage() + "\t" + message.getBinaryMessage() ); + } } } diff --git a/src/decode/p25/TrellisHalfRate.java b/src/decode/p25/TrellisHalfRate.java index b9064e1f..75a37372 100644 --- a/src/decode/p25/TrellisHalfRate.java +++ b/src/decode/p25/TrellisHalfRate.java @@ -2,10 +2,17 @@ package decode.p25; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import bits.BitSetBuffer; +import dsp.fsk.Dibit; +import dsp.fsk.P25MessageFramer; public class TrellisHalfRate { + private final static Logger mLog = LoggerFactory.getLogger( TrellisHalfRate.class ); + private ArrayList mConstellationNodes = new ArrayList(); @@ -56,38 +63,76 @@ public class TrellisHalfRate mConstellationNodes.clear(); } + + private String constellationsToString( String label ) + { + StringBuilder sb = new StringBuilder(); + + sb.append( label ); + + for( ConstellationNode node: mConstellationNodes ) + { + sb.append( " " + node.getConstellation().name() ); + } + + return sb.toString(); + } + + private String inputsToString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( " INPUTS: " ); + + for( ConstellationNode node: mConstellationNodes ) + { + sb.append( " " ); + sb.append( ( node.getConstellation().getInput().getBit1() ? "1" : "0" ) ); + sb.append( ( node.getConstellation().getInput().getBit2() ? "1" : "0" ) ); + } + + return sb.toString(); + } public void decode( BitSetBuffer message, int start, int end ) { - /* load each of the nodes with deinterleaved constellations */ + /* load each of the nodes with de-interleaved constellations */ for( int index = 0; index < 49; index++ ) { - Constellation c = getConstellation( message, index * 4 ); - + Constellation c = getConstellation( message, start + index * 4 ); + mConstellationNodes.get( index ).setConstellation( c ); } +// mLog.debug( constellationsToString( " LOADED: ") ); +// /* test to see if constellations are correct - otherwise correct them */ ConstellationNode firstNode = mConstellationNodes.get( 0 ); - if( !firstNode.startsWith( Dibit.D0 ) || !firstNode.isCorrect() ) + if( !firstNode.hasStateDibit( Dibit.D00_PLUS_1 ) || !firstNode.isCorrect() ) { - firstNode.correctTo( Dibit.D0 ); + firstNode.correctTo( Dibit.D00_PLUS_1 ); } +// mLog.debug( constellationsToString( "CORRECTD: " ) ); +// +// mLog.debug( inputsToString() ); +// /* clear constellations from original message */ message.clear( start, end ); - /* replace with decoded values from the nodes */ + /* replace with decoded values from the constellation nodes */ for( int index = 0; index < 49; index++ ) { ConstellationNode node = mConstellationNodes.get( index ); - if( node.firstBit() ) + Dibit input = node.getInputDibit(); + + if( input.getBit1() ) { message.set( start + ( index * 2 ) ); } - if( node.secondBit() ) + if( input.getBit2() ) { message.set( start + ( index * 2 ) + 1 ); } @@ -96,17 +141,17 @@ public class TrellisHalfRate private Constellation getConstellation( BitSetBuffer message, int index ) { - int constellation = 0; + int transmittedValue = 0; for( int x = 0; x < 4; x++ ) { if( message.get( index + x ) ) { - constellation += ( 1 << ( 3 - x ) ); + transmittedValue += ( 1 << ( 3 - x ) ); } } - return Constellation.fromValue( constellation ); + return Constellation.fromTransmittedValue( transmittedValue ); } public class ConstellationNode @@ -124,19 +169,19 @@ public class TrellisHalfRate mConnectedNode = null; } - public boolean startsWith( Dibit dibit ) + public Constellation getConstellation() { - return mConstellation.getLeft() == dibit; + return mConstellation; } - public boolean firstBit() + public Dibit getInputDibit() { - return mConstellation.getRight().firstBit(); + return mConstellation.getInput(); } - public boolean secondBit() + public boolean hasStateDibit( Dibit dibit ) { - return mConstellation.getRight().secondBit(); + return mConstellation.getState() == dibit; } /** @@ -147,50 +192,52 @@ public class TrellisHalfRate * corrective sequence by invoking this method with Dibit.D0 on the * first node. * - * @param dibit to use for the left side. + * @param stateDibit to use for the left side. */ - public void correctTo( Dibit dibit ) + public void correctTo( Dibit stateDibit ) { - if( mCorrect && mConstellation.getLeft() == dibit ) + if( mCorrect && mConstellation.getState() == stateDibit ) { return; } if( isCurrentConnectionCorrect() ) { - mConstellation = Constellation. - fromDibits( dibit, mConstellation.getRight() ); + mConstellation = Constellation.fromStateAndInputDibits( stateDibit, + mConstellation.getInput() ); mCorrect = true; if( mConnectedNode != null ) { - mConnectedNode.correctTo( mConstellation.getRight() ); + /* the next node's state was this node's input */ + mConnectedNode.correctTo( mConstellation.getInput() ); } } else { - Constellation cheapest = mConstellation; + Constellation cheapestConstellation = mConstellation; - int cost = 100; //arbitrary + int cheapestCost = 100; //arbitrary - for( Dibit d: Dibit.values() ) + for( Dibit testInput: Dibit.values() ) { - Constellation test = Constellation.fromDibits( dibit, d ); + Constellation testConstellation = Constellation + .fromStateAndInputDibits( stateDibit, testInput ); - int testCost = mConstellation.costTo( test ) + - mConnectedNode.costTo( d ); + int testCost = mConstellation.costTo( testConstellation ) + + mConnectedNode.costTo( testInput ); - if( testCost < cost ) + if( testCost < cheapestCost ) { - cost = testCost; - cheapest = test; + cheapestCost = testCost; + cheapestConstellation = testConstellation; } } - mConstellation = cheapest; + mConstellation = cheapestConstellation; - mConnectedNode.correctTo( mConstellation.getRight() ); + mConnectedNode.correctTo( mConstellation.getInput() ); mCorrect = true; } @@ -198,18 +245,18 @@ public class TrellisHalfRate /** * Calculates the cost (hamming distance) of using the argument as the - * left side dibit for the current node, and recursively finding the - * cheapest corresponding right dibit. + * state dibit for the current node, and recursively finding the + * cheapest corresponding input dibit. * - * @param leftTest + * @param stateTest * @return */ - public int costTo( Dibit leftTest ) + public int costTo( Dibit stateTest ) { if( isCurrentConnectionCorrect() ) { - Constellation c = Constellation. - fromDibits( leftTest, mConstellation.getRight() ); + Constellation c = Constellation.fromStateAndInputDibits( + stateTest, mConstellation.getInput() ); return mConstellation.costTo( c ); } @@ -217,12 +264,13 @@ public class TrellisHalfRate { int cheapestCost = 100; //arbitrary - for( Dibit d: Dibit.values() ) + for( Dibit inputTest: Dibit.values() ) { - Constellation c = Constellation.fromDibits( leftTest, d ); + Constellation constellationTest = + Constellation.fromStateAndInputDibits( stateTest, inputTest ); - int cost = mConnectedNode.costTo( d ) + - mConstellation.costTo( c ); + int cost = mConnectedNode.costTo( inputTest ) + + mConstellation.costTo( constellationTest ); if( cost < cheapestCost ) { @@ -235,12 +283,12 @@ public class TrellisHalfRate } /** - * Indicates if the immediate connection is correct + * Indicates if the immediate connection to the right is correct */ public boolean isCurrentConnectionCorrect() { return ( mConnectedNode == null || - mConstellation.getRight() == mConnectedNode.getLeft() ); + mConstellation.getInput() == mConnectedNode.getStateDibit() ); } /** @@ -267,15 +315,15 @@ public class TrellisHalfRate else { mCorrect = mConnectedNode.isCorrect() && - mConstellation.getRight() == mConnectedNode.getLeft(); + mConstellation.getInput() == mConnectedNode.getStateDibit(); } return mCorrect; } - public Dibit getLeft() + public Dibit getStateDibit() { - return mConstellation.getLeft(); + return mConstellation.getState(); } public void setConstellation( Constellation constellation ) @@ -292,157 +340,154 @@ public class TrellisHalfRate public enum Constellation { - C0( Dibit.D1, Dibit.D1, 0 ), - C1( Dibit.D0, Dibit.D2, 1 ), - C2( Dibit.D0, Dibit.D0, 2 ), - C3( Dibit.D1, Dibit.D3, 3 ), - C4( Dibit.D2, Dibit.D3, 4 ), - C5( Dibit.D3, Dibit.D0, 5 ), - C6( Dibit.D3, Dibit.D2, 6 ), - C7( Dibit.D2, Dibit.D1, 7 ), - C8( Dibit.D3, Dibit.D3, 8 ), - C9( Dibit.D2, Dibit.D0, 9 ), - CA( Dibit.D2, Dibit.D2, 10 ), - CB( Dibit.D3, Dibit.D1, 11 ), - CC( Dibit.D0, Dibit.D1, 12 ), - CD( Dibit.D1, Dibit.D2, 13 ), - CE( Dibit.D1, Dibit.D0, 14 ), - CF( Dibit.D0, Dibit.D3, 15 ); + /* State (previous), Input (next), Transmit 1, Transmit 2 */ + CB( Dibit.D01_PLUS_3, Dibit.D01_PLUS_3, Dibit.D00_PLUS_1, Dibit.D00_PLUS_1, 0 ), + CC( Dibit.D00_PLUS_1, Dibit.D10_MINUS_1, Dibit.D00_PLUS_1, Dibit.D01_PLUS_3, 1 ), + C0( Dibit.D00_PLUS_1, Dibit.D00_PLUS_1, Dibit.D00_PLUS_1, Dibit.D10_MINUS_1, 2 ), + C7( Dibit.D01_PLUS_3, Dibit.D11_MINUS_3, Dibit.D00_PLUS_1, Dibit.D11_MINUS_3, 3 ), + CE( Dibit.D10_MINUS_1, Dibit.D11_MINUS_3, Dibit.D01_PLUS_3, Dibit.D00_PLUS_1, 4 ), + C9( Dibit.D11_MINUS_3, Dibit.D00_PLUS_1, Dibit.D01_PLUS_3, Dibit.D01_PLUS_3, 5 ), + C5( Dibit.D11_MINUS_3, Dibit.D10_MINUS_1, Dibit.D01_PLUS_3, Dibit.D10_MINUS_1, 6 ), + C2( Dibit.D10_MINUS_1, Dibit.D01_PLUS_3, Dibit.D01_PLUS_3, Dibit.D11_MINUS_3, 7 ), + CA( Dibit.D11_MINUS_3, Dibit.D11_MINUS_3, Dibit.D10_MINUS_1, Dibit.D00_PLUS_1, 8 ), + CD( Dibit.D10_MINUS_1, Dibit.D00_PLUS_1, Dibit.D10_MINUS_1, Dibit.D01_PLUS_3, 9 ), + C1( Dibit.D10_MINUS_1, Dibit.D10_MINUS_1, Dibit.D10_MINUS_1, Dibit.D10_MINUS_1, 10 ), + C6( Dibit.D11_MINUS_3, Dibit.D01_PLUS_3, Dibit.D10_MINUS_1, Dibit.D11_MINUS_3, 11 ), + CF( Dibit.D00_PLUS_1, Dibit.D01_PLUS_3, Dibit.D11_MINUS_3, Dibit.D00_PLUS_1, 12 ), + C8( Dibit.D01_PLUS_3, Dibit.D10_MINUS_1, Dibit.D11_MINUS_3, Dibit.D01_PLUS_3, 13 ), + C4( Dibit.D01_PLUS_3, Dibit.D00_PLUS_1, Dibit.D11_MINUS_3, Dibit.D10_MINUS_1, 14 ), + C3( Dibit.D00_PLUS_1, Dibit.D11_MINUS_3, Dibit.D11_MINUS_3, Dibit.D11_MINUS_3, 15 ); - private Dibit mLeftDibit; - private Dibit mRightDibit; - private int mValue; + private Dibit mStateDibit; + private Dibit mInputDibit; + private Dibit mTransmitDibit1; + private Dibit mTransmitDibit2; + private int mTransmittedValue; - private Constellation( Dibit leftDibit, Dibit rightDibit, int value ) + private Constellation( Dibit stateDibit, + Dibit inputDibit, + Dibit transmitDibit1, + Dibit transmitDibit2, + int transmittedValue ) { - mLeftDibit = leftDibit; - mRightDibit = rightDibit; - mValue = value; + mStateDibit = stateDibit; + mInputDibit = inputDibit; + mTransmitDibit1 = transmitDibit1; + mTransmitDibit2 = transmitDibit2; + mTransmittedValue = transmittedValue; } - public Dibit getLeft() + public Dibit getState() { - return mLeftDibit; + return mStateDibit; } - public Dibit getRight() + public Dibit getInput() { - return mRightDibit; + return mInputDibit; } - public int getValue() + public Dibit getTransmitDibit1() { - return mValue; + return mTransmitDibit1; } - public static Constellation fromValue( int value ) + public Dibit getTransmitDibit2() + { + return mTransmitDibit2; + } + + public int getTransmittedValue() + { + return mTransmittedValue; + } + + public static Constellation fromTransmittedValue( int value ) { if( 0 <= value && value <= 15 ) { - return Constellation.values()[ value ]; + return values()[ value ]; } return null; } + public static Constellation fromTransmittedDibits( Dibit left, Dibit right ) + { + return fromTransmittedValue( left.getHighValue() + right.getLowValue() ); + } + + public static Constellation fromStateAndInputDibits( Dibit state, Dibit input ) + { + switch( state ) + { + case D00_PLUS_1: + switch( input ) + { + case D00_PLUS_1: + return C0; + case D01_PLUS_3: + return CF; + case D10_MINUS_1: + return CC; + case D11_MINUS_3: + return C3; + } + break; + case D01_PLUS_3: + switch( input ) + { + case D00_PLUS_1: + return C4; + case D01_PLUS_3: + return CB; + case D10_MINUS_1: + return C8; + case D11_MINUS_3: + return C7; + } + break; + case D10_MINUS_1: + switch( input ) + { + case D00_PLUS_1: + return CD; + case D01_PLUS_3: + return C2; + case D10_MINUS_1: + return C1; + case D11_MINUS_3: + return CE; + } + break; + case D11_MINUS_3: + switch( input ) + { + case D00_PLUS_1: + return C9; + case D01_PLUS_3: + return C6; + case D10_MINUS_1: + return C5; + case D11_MINUS_3: + return CA; + } + break; + } + + /* Should never get to here */ + return C0; + } + /** * Returns the cost or hamming distance to the other constellation using * the values from the constellation costs table */ public int costTo( Constellation other ) { - return CONSTELLATION_COSTS[ getValue() ][ other.getValue() ]; + return CONSTELLATION_COSTS[ getTransmittedValue() ][ other.getTransmittedValue() ]; } - public static Constellation fromDibits( Dibit left, Dibit right ) - { - switch( left ) - { - case D0: - switch( right ) - { - case D0: - return C2; - case D1: - return CC; - case D2: - return C1; - case D3: - return CF; - default: - } - case D1: - switch( right ) - { - case D0: - return CE; - case D1: - return C0; - case D2: - return CD; - case D3: - return C3; - default: - } - case D2: - switch( right ) - { - case D0: - return C9; - case D1: - return C7; - case D2: - return CA; - case D3: - return C4; - default: - } - case D3: - switch( right ) - { - case D0: - return C5; - case D1: - return CB; - case D2: - return C6; - case D3: - return C8; - default: - } - default: - } - - /* we should never get to here */ - return C0; - } - } - - public enum Dibit - { - D0( false, false ), - D1( false, true ), - D2( true, false ), - D3( true, true ); - - private boolean mFirstBit; - private boolean mSecondBit; - - private Dibit( boolean firstBit, boolean secondBit ) - { - mFirstBit = firstBit; - mSecondBit = secondBit; - } - - public boolean firstBit() - { - return mFirstBit; - } - - public boolean secondBit() - { - return mSecondBit; - } } /** @@ -450,21 +495,21 @@ public class TrellisHalfRate */ public static void main( String[] args ) { - String original = "00100110000001111000101111110011111000011110100111100001000100100010001011000000110101111110001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010111110111110110000110101001011110101"; + String original = "00100110000001111000101111110011111000011110100111100001000100100010110000001101100100100010001000100010001000101100111000100010111110001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000101100001110000101000110011100001110"; - BitSetBuffer bufferOriginal = new BitSetBuffer( 260 ); + BitSetBuffer buffer = new BitSetBuffer( original.length() ); try { - for( int x = 0; x < 260; x++ ) + for( int x = 0; x < original.length(); x++ ) { if( original.substring( x, x + 1 ).contentEquals( "0" ) ) { - bufferOriginal.add( false ); + buffer.add( false ); } else { - bufferOriginal.add( true ); + buffer.add( true ); } } } @@ -473,12 +518,13 @@ public class TrellisHalfRate e.printStackTrace(); } - System.out.println( " ORIGINAL: " + original ); + mLog.debug( "ORIGINAL: " + original ); + mLog.debug( " BUFFER: " + buffer.toString() ); TrellisHalfRate t = new TrellisHalfRate(); - t.decode( bufferOriginal, 64, 260 ); - System.out.println( "ORIG DECODED: " + bufferOriginal.toString() ); - + t.decode( buffer, 64, original.length() ); + mLog.debug( " DECODED: " + buffer.toString() ); + mLog.debug( "Finished!" ); } } diff --git a/src/decode/p25/message/P25Message.java b/src/decode/p25/message/P25Message.java index b7cc5572..ddaa2435 100644 --- a/src/decode/p25/message/P25Message.java +++ b/src/decode/p25/message/P25Message.java @@ -54,7 +54,7 @@ public class P25Message extends Message sb.append( "NAC:" ); sb.append( getNAC() ); sb.append( " " ); - sb.append( getDUID().name() ); + sb.append( getDUID().getLabel() ); return sb.toString(); } @@ -74,7 +74,7 @@ public class P25Message extends Message @Override public String getEventType() { - return mDUID.name(); + return "P25 " + mDUID.name(); } @Override diff --git a/src/decode/p25/message/pdu/PDUMessage.java b/src/decode/p25/message/pdu/PDUMessage.java index 2f230714..6a078bb8 100644 --- a/src/decode/p25/message/pdu/PDUMessage.java +++ b/src/decode/p25/message/pdu/PDUMessage.java @@ -117,7 +117,7 @@ public class PDUMessage extends P25Message sb.append( "NAC:" ); sb.append( getNAC() ); sb.append( " " ); - sb.append( getDUID().name() ); + sb.append( getDUID().getLabel() ); sb.append( " " ); sb.append( getConfirmation() ); sb.append( " " ); diff --git a/src/decode/p25/message/tsbk/GroupChannelGrant.java b/src/decode/p25/message/tsbk/GroupChannelGrant.java index 5e78f134..847dc975 100644 --- a/src/decode/p25/message/tsbk/GroupChannelGrant.java +++ b/src/decode/p25/message/tsbk/GroupChannelGrant.java @@ -34,7 +34,7 @@ public abstract class GroupChannelGrant extends ChannelGrant { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); if( isEmergency() ) { diff --git a/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java b/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java index 82ebc7ca..8d0a95e4 100644 --- a/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java +++ b/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java @@ -26,7 +26,7 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); if( isEmergency() ) { diff --git a/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java b/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java index 0d6cbb17..7703ab08 100644 --- a/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java +++ b/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java @@ -29,7 +29,7 @@ public abstract class GroupMultiChannelGrant extends ChannelGrant { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " CHAN1:" ); sb.append( getChannelID1() + "/" + getChannelNumber1() ); diff --git a/src/decode/p25/message/tsbk/TSBKMessage.java b/src/decode/p25/message/tsbk/TSBKMessage.java index e6bc36a7..fec05dbc 100644 --- a/src/decode/p25/message/tsbk/TSBKMessage.java +++ b/src/decode/p25/message/tsbk/TSBKMessage.java @@ -60,25 +60,55 @@ public class TSBKMessage extends P25Message { StringBuilder sb = new StringBuilder(); - Vendor vendor = getVendor(); + sb.append( getMessageStub() ); - sb.append( " SYSTEM:" ); - sb.append( getNAC() ); /* NAC is the system id for TSBK messages */ - sb.append( " " ); - sb.append( getDUID().name() ); - sb.append( " VEND:" ); - sb.append( vendor.getLabel() ); - - if( isEncrypted() ) - { - sb.append( " ENCRYPTED" ); - } - - sb.append( " " + getMessageHex() ); + sb.append( " - " + getMessageHex() ); return sb.toString(); } + protected String getMessageStub() + { + StringBuilder sb = new StringBuilder(); + + Vendor vendor = getVendor(); + + sb.append( "SYS:" ); + sb.append( getNAC() ); /* NAC is the system id for TSBK messages */ + sb.append( " " ); + sb.append( getDUID().getLabel() ); + + if( vendor == Vendor.STANDARD ) + { + if( isEncrypted() ) + { + sb.append( " ENCRYPTED" ); + } + else + { + sb.append( " " ); + sb.append( getOpcode().getLabel() ); + } + } + else + { + sb.append( " " ); + sb.append( vendor.getLabel() ); + + if( isEncrypted() ) + { + sb.append( " ENCRYPTED" ); + } + else + { + sb.append( " OPCD:" ); + sb.append( mMessage.getHex( OPCODE, 2 ) ); + } + } + + return sb.toString(); + } + public String getMessageHex() { StringBuilder sb = new StringBuilder(); diff --git a/src/decode/p25/message/tsbk/TSBKMessageFactory.java b/src/decode/p25/message/tsbk/TSBKMessageFactory.java index 634d056f..fee8444a 100644 --- a/src/decode/p25/message/tsbk/TSBKMessageFactory.java +++ b/src/decode/p25/message/tsbk/TSBKMessageFactory.java @@ -47,7 +47,7 @@ public class TSBKMessageFactory DataUnitID duid, AliasList aliasList ) { - int opcode = message.getInt( TSBKMessage.OPCODE ); + Opcode opcode = Opcode.fromValue( message.getInt( TSBKMessage.OPCODE ) ); Vendor vendor = Vendor.fromValue( message.getInt( TSBKMessage.VENDOR_ID ) ); @@ -55,7 +55,7 @@ public class TSBKMessageFactory switch( vendor ) { case STANDARD: - switch( Opcode.fromValue( opcode ) ) + switch( opcode ) { case ACKNOWLEDGE_RESPONSE_FNE: return new AcknowledgeResponse( message, duid, @@ -98,6 +98,7 @@ public class TSBKMessageFactory return new GroupVoiceChannelGrantUpdateExplicit( message, duid, aliasList ); case IDENTIFIER_UPDATE: + case IDENTIFIER_UPDATE_VHF_UHF_BANDS: return new IdentifierUpdate( message, duid, aliasList ); case INDIVIDUAL_DATA_CHANNEL_GRANT: return new IndividualDataChannelGrant( message, duid, diff --git a/src/decode/p25/message/tsbk/UnitChannelGrant.java b/src/decode/p25/message/tsbk/UnitChannelGrant.java index 57b1f4e3..fc718d76 100644 --- a/src/decode/p25/message/tsbk/UnitChannelGrant.java +++ b/src/decode/p25/message/tsbk/UnitChannelGrant.java @@ -24,7 +24,7 @@ public abstract class UnitChannelGrant extends ChannelGrant { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); if( isEmergency() ) { diff --git a/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java b/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java index d08e0ac9..9d52b7a3 100644 --- a/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java @@ -37,7 +37,7 @@ public class AcknowledgeResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SVC TYPE: " + getServiceType() ); diff --git a/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java index 2ee521b9..0071ea3e 100644 --- a/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java @@ -40,7 +40,7 @@ public class AdjacentStatusBroadcast extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " LRA:" + getLocationRegistrationArea() ); diff --git a/src/decode/p25/message/tsbk/osp/control/AuthenticationCommand.java b/src/decode/p25/message/tsbk/osp/control/AuthenticationCommand.java index 97009321..6ebb2f13 100644 --- a/src/decode/p25/message/tsbk/osp/control/AuthenticationCommand.java +++ b/src/decode/p25/message/tsbk/osp/control/AuthenticationCommand.java @@ -32,7 +32,7 @@ public class AuthenticationCommand extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " WACN: " + getWACN() ); sb.append( " SYS ID: " + getSystemID() ); diff --git a/src/decode/p25/message/tsbk/osp/control/CallAlert.java b/src/decode/p25/message/tsbk/osp/control/CallAlert.java index ddda7e02..9e51bebf 100644 --- a/src/decode/p25/message/tsbk/osp/control/CallAlert.java +++ b/src/decode/p25/message/tsbk/osp/control/CallAlert.java @@ -30,7 +30,7 @@ public class CallAlert extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SRC ID: " + getSourceID() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/DenyResponse.java b/src/decode/p25/message/tsbk/osp/control/DenyResponse.java index b2e8b7d6..3f8927a1 100644 --- a/src/decode/p25/message/tsbk/osp/control/DenyResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/DenyResponse.java @@ -35,7 +35,7 @@ public class DenyResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/ExtendedFunctionCommand.java b/src/decode/p25/message/tsbk/osp/control/ExtendedFunctionCommand.java index f55a94dc..644543d7 100644 --- a/src/decode/p25/message/tsbk/osp/control/ExtendedFunctionCommand.java +++ b/src/decode/p25/message/tsbk/osp/control/ExtendedFunctionCommand.java @@ -31,7 +31,7 @@ public class ExtendedFunctionCommand extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " EXTENDED FUNCTION:" + getExtendedFunction() ); diff --git a/src/decode/p25/message/tsbk/osp/control/GroupAffiliationQuery.java b/src/decode/p25/message/tsbk/osp/control/GroupAffiliationQuery.java index b0266f09..6047b4de 100644 --- a/src/decode/p25/message/tsbk/osp/control/GroupAffiliationQuery.java +++ b/src/decode/p25/message/tsbk/osp/control/GroupAffiliationQuery.java @@ -30,7 +30,7 @@ public class GroupAffiliationQuery extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SRC ADDR: " + getSourceAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/GroupAffiliationResponse.java b/src/decode/p25/message/tsbk/osp/control/GroupAffiliationResponse.java index b6d70b05..1ce31817 100644 --- a/src/decode/p25/message/tsbk/osp/control/GroupAffiliationResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/GroupAffiliationResponse.java @@ -35,7 +35,7 @@ public class GroupAffiliationResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " AFFILIATION:" + getResponse().name() ); sb.append( " ANNOUNCE GROUP:" + getAnnouncementGroupAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java b/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java index 1dcbc87d..b5671515 100644 --- a/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java +++ b/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java @@ -26,8 +26,8 @@ public class IdentifierUpdate extends TSBKMessage 137,138,139,140,141,142,143 }; public IdentifierUpdate( BitSetBuffer message, - DataUnitID duid, - AliasList aliasList ) + DataUnitID duid, + AliasList aliasList ) { super( message, duid, aliasList ); } @@ -35,14 +35,14 @@ public class IdentifierUpdate extends TSBKMessage @Override public String getEventType() { - return Opcode.IDENTIFIER_UPDATE.getDescription(); + return getOpcode().getDescription(); } public String getMessage() { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " CHAN:" + getIdentifier() ); diff --git a/src/decode/p25/message/tsbk/osp/control/LocationRegistrationResponse.java b/src/decode/p25/message/tsbk/osp/control/LocationRegistrationResponse.java index eacef6b2..af81697b 100644 --- a/src/decode/p25/message/tsbk/osp/control/LocationRegistrationResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/LocationRegistrationResponse.java @@ -34,7 +34,7 @@ public class LocationRegistrationResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " REGISTRATION:" + getResponse().name() ); sb.append( " GROUP:" + getGroupAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/MessageUpdate.java b/src/decode/p25/message/tsbk/osp/control/MessageUpdate.java index 79b84e2b..34f74bb5 100644 --- a/src/decode/p25/message/tsbk/osp/control/MessageUpdate.java +++ b/src/decode/p25/message/tsbk/osp/control/MessageUpdate.java @@ -32,7 +32,7 @@ public class MessageUpdate extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " MSG:" + getShortDataMessage() ); sb.append( " SRC ADDR: " + getSourceAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java index 76d31d2a..922b22fd 100644 --- a/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java @@ -36,7 +36,7 @@ public class NetworkStatusBroadcast extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " LRA:" + getLocationRegistrationArea() ); diff --git a/src/decode/p25/message/tsbk/osp/control/ProtectionParameterUpdate.java b/src/decode/p25/message/tsbk/osp/control/ProtectionParameterUpdate.java index 370d33dd..7ad8e2ad 100644 --- a/src/decode/p25/message/tsbk/osp/control/ProtectionParameterUpdate.java +++ b/src/decode/p25/message/tsbk/osp/control/ProtectionParameterUpdate.java @@ -32,7 +32,7 @@ public class ProtectionParameterUpdate extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/QueuedResponse.java b/src/decode/p25/message/tsbk/osp/control/QueuedResponse.java index 4ec34647..0b1b372e 100644 --- a/src/decode/p25/message/tsbk/osp/control/QueuedResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/QueuedResponse.java @@ -35,7 +35,7 @@ public class QueuedResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java index 0910f99a..21042adf 100644 --- a/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java @@ -37,7 +37,7 @@ public class RFSSStatusBroadcast extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " LRA:" + getLocationRegistrationArea() ); diff --git a/src/decode/p25/message/tsbk/osp/control/RadioUnitMonitorCommand.java b/src/decode/p25/message/tsbk/osp/control/RadioUnitMonitorCommand.java index 52885b3f..cc5e1200 100644 --- a/src/decode/p25/message/tsbk/osp/control/RadioUnitMonitorCommand.java +++ b/src/decode/p25/message/tsbk/osp/control/RadioUnitMonitorCommand.java @@ -31,7 +31,7 @@ public class RadioUnitMonitorCommand extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " MULT:" + getTransmitMultiplier() ); sb.append( " SRC ADDR: " + getSourceAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/RoamingAddressCommand.java b/src/decode/p25/message/tsbk/osp/control/RoamingAddressCommand.java index c05016a6..c392bf14 100644 --- a/src/decode/p25/message/tsbk/osp/control/RoamingAddressCommand.java +++ b/src/decode/p25/message/tsbk/osp/control/RoamingAddressCommand.java @@ -35,7 +35,7 @@ public class RoamingAddressCommand extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( getStackOperation().name() ); sb.append( " WACN:" + getWACN() ); diff --git a/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java b/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java index 94fe95c3..4f404d0a 100644 --- a/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java @@ -36,7 +36,7 @@ public class SecondaryControlChannelBroadcast extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " RFSS:" + getRFSS() ); diff --git a/src/decode/p25/message/tsbk/osp/control/StatusQuery.java b/src/decode/p25/message/tsbk/osp/control/StatusQuery.java index 2d002e19..9d55e4b8 100644 --- a/src/decode/p25/message/tsbk/osp/control/StatusQuery.java +++ b/src/decode/p25/message/tsbk/osp/control/StatusQuery.java @@ -30,7 +30,7 @@ public class StatusQuery extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SRC ADDR: " + getSourceAddress() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/StatusUpdate.java b/src/decode/p25/message/tsbk/osp/control/StatusUpdate.java index b96d5a87..091557c4 100644 --- a/src/decode/p25/message/tsbk/osp/control/StatusUpdate.java +++ b/src/decode/p25/message/tsbk/osp/control/StatusUpdate.java @@ -32,7 +32,7 @@ public class StatusUpdate extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " STATUS USER:" + getUserStatus() ); sb.append( " UNIT:" + getUnitStatus() ); diff --git a/src/decode/p25/message/tsbk/osp/control/SystemServiceBroadcast.java b/src/decode/p25/message/tsbk/osp/control/SystemServiceBroadcast.java index 6c48a4de..52f4d0b8 100644 --- a/src/decode/p25/message/tsbk/osp/control/SystemServiceBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/SystemServiceBroadcast.java @@ -35,7 +35,7 @@ public class SystemServiceBroadcast extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SERVICES AVAILABLE " ); diff --git a/src/decode/p25/message/tsbk/osp/control/UnitDeregistrationAcknowledge.java b/src/decode/p25/message/tsbk/osp/control/UnitDeregistrationAcknowledge.java index 0402bede..b0614202 100644 --- a/src/decode/p25/message/tsbk/osp/control/UnitDeregistrationAcknowledge.java +++ b/src/decode/p25/message/tsbk/osp/control/UnitDeregistrationAcknowledge.java @@ -33,7 +33,7 @@ public class UnitDeregistrationAcknowledge extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " WACN:" + getWACN() ); sb.append( " SYSTEM:" + getSystemID() ); diff --git a/src/decode/p25/message/tsbk/osp/control/UnitRegistrationCommand.java b/src/decode/p25/message/tsbk/osp/control/UnitRegistrationCommand.java index 6a15cea3..87742d1f 100644 --- a/src/decode/p25/message/tsbk/osp/control/UnitRegistrationCommand.java +++ b/src/decode/p25/message/tsbk/osp/control/UnitRegistrationCommand.java @@ -30,7 +30,7 @@ public class UnitRegistrationCommand extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " SRC ADDR: " + getSourceAddress() ); sb.append( " TGT ADDR: " + getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/control/UnitRegistrationResponse.java b/src/decode/p25/message/tsbk/osp/control/UnitRegistrationResponse.java index 4cde5e23..1675e236 100644 --- a/src/decode/p25/message/tsbk/osp/control/UnitRegistrationResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/UnitRegistrationResponse.java @@ -33,7 +33,7 @@ public class UnitRegistrationResponse extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " REGISTRATION:" + getResponse().name() ); sb.append( " SYSTEM:" + getSystemID() ); diff --git a/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectAnswerRequest.java b/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectAnswerRequest.java index 42be5891..248a47cd 100644 --- a/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectAnswerRequest.java +++ b/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectAnswerRequest.java @@ -38,7 +38,7 @@ public class TelephoneInterconnectAnswerRequest extends TSBKMessage { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); sb.append( " TO:" ); sb.append( getTargetAddress() ); diff --git a/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectVoiceChannelGrant.java b/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectVoiceChannelGrant.java index b67e8ae9..4128c42d 100644 --- a/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectVoiceChannelGrant.java +++ b/src/decode/p25/message/tsbk/osp/voice/TelephoneInterconnectVoiceChannelGrant.java @@ -22,7 +22,7 @@ public class TelephoneInterconnectVoiceChannelGrant extends UnitChannelGrant { StringBuilder sb = new StringBuilder(); - sb.append( super.getMessage() ); + sb.append( getMessageStub() ); if( isEmergency() ) { diff --git a/src/decode/p25/reference/DataUnitID.java b/src/decode/p25/reference/DataUnitID.java index 08f9ea6b..2b189ad1 100644 --- a/src/decode/p25/reference/DataUnitID.java +++ b/src/decode/p25/reference/DataUnitID.java @@ -6,31 +6,34 @@ package decode.p25.reference; */ public enum DataUnitID { - NID ( -1, 64, "Network and Data Unit ID", false ), - HDU ( 0, 722, "Header Data Unit", false ), - TDU ( 3, 64, "Simple Terminator Data Unit", false ), - LDU1 ( 5, 1630, "Logical Link Data Unit 1", true ), - TSBK1( 7, 260, "Trunking Signaling Block", false ), //Single Block - TSBK2( 7, 260, "Trunking Signaling Block", false ), //Single Block - TSBK3( 7, 260, "Trunking Signaling Block", false ), //Single Block - LDU2 ( 10, 1632, "Logical Link Data Unit 2", true ), - PDU1 ( 12, 456, "Packet Data Unit", false ), - PDU2 ( 12, 652, "Packet Data Unit", false ), - PDU3 ( 12, 848, "Packet Data Unit", false ), - TDULC( 15, 372, "Terminator Data Unit With Link Control", false ), - UNKN ( -1, 0, "Unknown", false ); + NID ( -1, 64, false, "NID ", "Network and Data Unit ID" ), + HDU ( 0, 722, false, "HDU ", "Header Data Unit" ), + TDU ( 3, 64, false, "TDU ", "Simple Terminator Data Unit" ), + LDU1 ( 5, 1630, true, "LDU1 ", "Logical Link Data Unit 1" ), + TSBK1( 7, 260, false, "TSBK1", "Trunking Signaling Block" ), + TSBK2( 7, 260, false, "TSBK2", "Trunking Signaling Block" ), + TSBK3( 7, 260, false, "TSBK3", "Trunking Signaling Block" ), + LDU2 ( 10, 1632, true, "LDU2 ", "Logical Link Data Unit 2" ), + PDU1 ( 12, 456, false, "PDU1 ", "Packet Data Unit" ), + PDU2 ( 12, 652, false, "PDU2 ", "Packet Data Unit" ), + PDU3 ( 12, 848, false, "PDU3 ", "Packet Data Unit" ), + TDULC( 15, 372, false, "TDULC", "Terminator Data Unit With Link Control" ), + UNKN ( -1, 0, false, "UNKWN", "Unknown" ); private int mValue; private int mMessageLength; - private String mLabel; private boolean mParity; + private String mLabel; + private String mDescription; - private DataUnitID( int value, int length, String label, boolean parity ) + private DataUnitID( int value, int length, boolean parity, String label, + String description ) { mValue = value; mMessageLength = length; - mLabel = label; mParity = parity; + mLabel = label; + mDescription = description; } public int getValue() @@ -48,6 +51,11 @@ public enum DataUnitID return mLabel; } + public String getDescription() + { + return mDescription; + } + public boolean getParity() { return mParity; diff --git a/src/decode/p25/reference/Opcode.java b/src/decode/p25/reference/Opcode.java index c857a7d1..6f963e20 100644 --- a/src/decode/p25/reference/Opcode.java +++ b/src/decode/p25/reference/Opcode.java @@ -2,81 +2,88 @@ package decode.p25.reference; public enum Opcode { - GROUP_VOICE_CHANNEL_GRANT( "Group Voice Channel Grant", 0 ), - RESERVED_01( "Reserved", 1 ), - GROUP_VOICE_CHANNEL_GRANT_UPDATE( "Group Voice Channel Grant Update", 2 ), - GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT( "Group Voice Channel Grant Update - Explicit", 3 ), - UNIT_TO_UNIT_VOICE_CHANNEL_GRANT( "Unit-to-Unit Voice Channel Grant", 4 ), - UNIT_TO_UNIT_ANSWER_REQUEST( "Unit-to-Unit Answer Request", 5 ), - UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE( "Unit-to-Unit Voice Channel Grant Update", 6 ), - RESERVED_07( "Reserved", 7 ), - TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT( "Telephone Interconnect Voice Channel Grant", 8 ), - TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE( "Telephone Interconnect Voice Channel Grant Update", 9 ), - TELEPHONE_INTERCONNECT_ANSWER_REQUEST( "Telephone Interconnect Answer Request", 10 ), - RESERVED_0B( "Reserved", 11 ), - RESERVED_0C( "Reserved", 12 ), - RESERVED_0D( "Reserved", 13 ), - RESERVED_0E( "Reserved", 14 ), - RESERVED_0F( "Reserved", 15 ), - INDIVIDUAL_DATA_CHANNEL_GRANT( "Individual Data Channel Grant", 16 ), - GROUP_DATA_CHANNEL_GRANT( "Group Data Channel Grant", 17 ), - GROUP_DATA_CHANNEL_ANNOUNCEMENT( "Group Data Channel Announcement", 18 ), - GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT( "Group Data Channel Announcement-Explicit", 19 ), - SNDCP_DATA_CHANNEL_GRANT( "SNDCP Data Channel Grant", 20 ), - SNDCP_DATA_PAGE_REQUEST( "SNDCP Data Page Request", 21 ), - SNDCP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT( "SNDCP Data Channel Announcement Explicit", 22 ), - RESERVED_17( "Reserved", 23 ), - STATUS_UPDATE( "Status Update", 24 ), - RESERVED_19( "Reserved", 25 ), - STATUS_QUERY( "Status Query", 26 ), - RESERVED_1B( "Reserved", 27 ), - MESSAGE_UPDATE( "Message Update", 28 ), - RADIO_UNIT_MONITOR_COMMAND( "Radio Unit Monitor Command", 29 ), - RESERVED_1E( "Reserved", 30 ), - CALL_ALERT( "Call Alert", 31 ), - ACKNOWLEDGE_RESPONSE_FNE( "Acknowledge Response - FNE", 32 ), - QUEUED_RESPONSE( "Queued Response", 33 ), - RESERVED_22( "Reserved", 34 ), - RESERVED_23( "Reserved", 35 ), - EXTENDED_FUNCTION_COMMAND( "Extended Function Command", 36 ), - RESERVED_25( "Reserved", 37 ), - RESERVED_26( "Reserved", 38 ), - DENY_RESPONSE( "Deny Response", 39 ), - GROUP_AFFILIATION_RESPONSE( "Group Affiliation Response", 40 ), - SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT( "Secondary Control Channel Broadcast-Explicit", 41 ), - GROUP_AFFILIATION_QUERY( "Group Affiliation Query", 42 ), - LOCATION_REGISTRATION_RESPONSE( "Location Registration Response", 43 ), - UNIT_REGISTRATION_RESPONSE( "Unit Registration Response", 44 ), - UNIT_REGISTRATION_COMMAND( "Unit Registration Command", 45 ), - AUTHENTICATION_COMMAND( "Authentication Command", 46 ), - UNIT_DEREGISTRATION_ACKNOWLEDGE( "De-Registration Acknowledge", 47 ), - RESERVED_30( "Reserved", 48 ), - RESERVED_31( "Reserved", 49 ), - RESERVED_32( "Reserved", 50 ), - RESERVED_33( "Reserved", 51 ), - IDENTIFIER_UPDATE_VHF_UHF_BANDS( "Identifier Update for VHF/UHF Bands", 52 ), - TIME_DATE_ANNOUNCEMENT( "Time and Date Announcement", 53 ), - ROAMING_ADDRESS_COMMAND( "Roaming Address Command", 54 ), - ROAMING_ADDRESS_UPDATE( "Roaming Address Update", 55 ), - SYSTEM_SERVICE_BROADCAST( "System Service Broadcast", 56 ), - SECONDARY_CONTROL_CHANNEL_BROADCAST( "Secondary Control Channel Broadcast", 57 ), - RFSS_STATUS_BROADCAST( "RFSS Status Broadcast", 58 ), - NETWORK_STATUS_BROADCAST( "Network Status Broadcast", 59 ), - ADJACENT_STATUS_BROADCAST( "Adjacent Status Broadcast", 60 ), - IDENTIFIER_UPDATE( "Identifier Update", 61 ), - PROTECTION_PARAMETER_BROADCAST( "Protection Parameter Broadcast", 62 ), - PROTECTION_PARAMETER_UPDATE( "Protection Parameter Update", 63 ), - UNKNOWN( "Unknown", -1 ); - + GROUP_VOICE_CHANNEL_GRANT( "GRP_VCH_GRANT ", "Group Voice Channel Grant", 0 ), + RESERVED_01( "RESERVED_01 ", "Reserved", 1 ), + GROUP_VOICE_CHANNEL_GRANT_UPDATE( "GRP_VCH_GRNT_UPD", "Group Voice Channel Grant Update", 2 ), + GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT( "GRP_VCH_GRNT_UPX", "Group Voice Channel Grant Update - Explicit", 3 ), + UNIT_TO_UNIT_VOICE_CHANNEL_GRANT( "UU_VCH_GRANT ", "Unit-to-Unit Voice Channel Grant", 4 ), + UNIT_TO_UNIT_ANSWER_REQUEST( "UU_ANS_REQ ", "Unit-to-Unit Answer Request", 5 ), + UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE( "UU_VCH_GRANT_UPD", "Unit-to-Unit Voice Channel Grant Update", 6 ), + RESERVED_07( "RESERVED_07 ", "Reserved", 7 ), + TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT( "TEL_INT_VCH_GRNT", "Telephone Interconnect Voice Channel Grant", 8 ), + TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE( "TEL_INT_VCH_GRNU","Telephone Interconnect Voice Channel Grant Update", 9 ), + TELEPHONE_INTERCONNECT_ANSWER_REQUEST( "TEL_INT_ANS_RQST", "Telephone Interconnect Answer Request", 10 ), + RESERVED_0B( "RESERVED_0B ", "Reserved", 11 ), + RESERVED_0C( "RESERVED_0C ", "Reserved", 12 ), + RESERVED_0D( "RESERVED_0D ", "Reserved", 13 ), + RESERVED_0E( "RESERVED_0E ", "Reserved", 14 ), + RESERVED_0F( "RESERVED_0F ", "Reserved", 15 ), + INDIVIDUAL_DATA_CHANNEL_GRANT( "IND_DCH_GRANT ", "Individual Data Channel Grant", 16 ), + GROUP_DATA_CHANNEL_GRANT( "GRP_DCH_GRANT ", "Group Data Channel Grant", 17 ), + GROUP_DATA_CHANNEL_ANNOUNCEMENT( "GRP_DCH_ANNOUNCE", "Group Data Channel Announcement", 18 ), + GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT( "GRP_DCH_ANNC_EXP", "Group Data Channel Announcement-Explicit", 19 ), + SNDCP_DATA_CHANNEL_GRANT( "SNDCP_DCH_GRANT ", "SNDCP Data Channel Grant", 20 ), + SNDCP_DATA_PAGE_REQUEST( "SNDCP_DCH_PAG_RQ", "SNDCP Data Page Request", 21 ), + SNDCP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT( "SNDCP_DCH_ANN_EX", "SNDCP Data Channel Announcement Explicit", 22 ), + RESERVED_17( "RESERVED_17 ", "Reserved", 23 ), + STATUS_UPDATE( "STATUS_UPDATE ", "Status Update", 24 ), + RESERVED_19( "RESERVED_19 ", "Reserved", 25 ), + STATUS_QUERY( "STATUS_QUERY ", "Status Query", 26 ), + RESERVED_1B( "RESERVED_1B ", "Reserved", 27 ), + MESSAGE_UPDATE( "MESSAGE_UPDATE ", "Message Update", 28 ), + RADIO_UNIT_MONITOR_COMMAND( "RADIO_MONITR_CMD", "Radio Unit Monitor Command", 29 ), + RESERVED_1E( "RESERVED_1E ", "Reserved", 30 ), + CALL_ALERT( "CALL_ALERT ", "Call Alert", 31 ), + ACKNOWLEDGE_RESPONSE_FNE( "ACK_RESPONSE_FNE", "Acknowledge Response - FNE", 32 ), + QUEUED_RESPONSE( "QUEUED_RESPONSE ", "Queued Response", 33 ), + RESERVED_22( "RESERVED_22 ", "Reserved", 34 ), + RESERVED_23( "RESERVED_23 ", "Reserved", 35 ), + EXTENDED_FUNCTION_COMMAND( "EXTNDED_FUNC_CMD", "Extended Function Command", 36 ), + RESERVED_25( "RESERVED_25 ", "Reserved", 37 ), + RESERVED_26( "RESERVED_26 ", "Reserved", 38 ), + DENY_RESPONSE( "DENY_RESPONSE ", "Deny Response", 39 ), + GROUP_AFFILIATION_RESPONSE( "GRP_AFFIL_RESP ", "Group Affiliation Response", 40 ), + SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT( "SCCB_CCH_BCST_EX", "Secondary Control Channel Broadcast-Explicit", 41 ), + GROUP_AFFILIATION_QUERY( "GRP_AFFIL_QUERY ", "Group Affiliation Query", 42 ), + LOCATION_REGISTRATION_RESPONSE( "LOCN_REG_RESPONS", "Location Registration Response", 43 ), + UNIT_REGISTRATION_RESPONSE( "UNIT_REG_RESPONS", "Unit Registration Response", 44 ), + UNIT_REGISTRATION_COMMAND( "UNIT_REG_COMMAND", "Unit Registration Command", 45 ), + AUTHENTICATION_COMMAND( "AUTH_COMMAND ", "Authentication Command", 46 ), + UNIT_DEREGISTRATION_ACKNOWLEDGE( "DE_REGIST_ACK ", "De-Registration Acknowledge", 47 ), + RESERVED_30( "RESERVED_30 ", "Reserved", 48 ), + RESERVED_31( "RESERVED_31 ", "Reserved", 49 ), + RESERVED_32( "RESERVED_32 ", "Reserved", 50 ), + RESERVED_33( "RESERVED_33 ", "Reserved", 51 ), + IDENTIFIER_UPDATE_VHF_UHF_BANDS( "IDEN_UPDATE_VUHF", "Identifier Update for VHF/UHF Bands", 52 ), + TIME_DATE_ANNOUNCEMENT( "TIME_DATE_ANNOUN", "Time and Date Announcement", 53 ), + ROAMING_ADDRESS_COMMAND( "ROAM_ADDR_CMD ", "Roaming Address Command", 54 ), + ROAMING_ADDRESS_UPDATE( "ROAM_ADDR_UPDATE", "Roaming Address Update", 55 ), + SYSTEM_SERVICE_BROADCAST( "SYS_SVC_BCAST ", "System Service Broadcast", 56 ), + SECONDARY_CONTROL_CHANNEL_BROADCAST( "SEC_CCH_BROADCST", "Secondary Control Channel Broadcast", 57 ), + RFSS_STATUS_BROADCAST( "RFSS_STATUS_BCST", "RFSS Status Broadcast", 58 ), + NETWORK_STATUS_BROADCAST( "NET_STATUS_BCAST", "Network Status Broadcast", 59 ), + ADJACENT_STATUS_BROADCAST( "NGHBR_STAT_BCAST", "Adjacent Status Broadcast", 60 ), + IDENTIFIER_UPDATE( "IDEN_UPDATE ", "Identifier Update", 61 ), + PROTECTION_PARAMETER_BROADCAST( "ENCRYPT_PAR_BCST", "Protection Parameter Broadcast", 62 ), + PROTECTION_PARAMETER_UPDATE( "ENCRYPT_PAR_UPDT", "Protection Parameter Update", 63 ), + UNKNOWN( "UNKNOWN ", "Unknown", -1 ); + + private String mLabel; private String mDescription; private int mCode; - private Opcode( String description, int code ) + private Opcode( String label, String description, int code ) { + mLabel = label; mDescription = description; mCode = code; } + public String getLabel() + { + return mLabel; + } + public String getDescription() { return mDescription; diff --git a/src/decode/p25/reference/Vendor.java b/src/decode/p25/reference/Vendor.java index 9072a1cc..7014b8e9 100644 --- a/src/decode/p25/reference/Vendor.java +++ b/src/decode/p25/reference/Vendor.java @@ -2,270 +2,272 @@ package decode.p25.reference; public enum Vendor { - STANDARD( "STANDARD", 0), - V1( "V_01", 1), - V2( "V_02", 2), - V3( "V_03", 3), - V4( "V_04", 4), - V5( "V_05", 5), - V6( "V_06", 6), - V7( "V_07", 7), - V8( "V_08", 8), - V9( "V_09", 9), - V10( "V_0A", 10), - V11( "V_0B", 11), - V12( "V_0C", 12), - V13( "V_0D", 13), - V14( "V_0E", 14), - V15( "V_0F", 15), - RELM( "RELM/BK RADIO", 16), - V17( "V_11", 17), - V18( "V_12", 18), - V19( "V_13", 19), - V20( "V_14", 20), - V21( "V_15", 21), - V22( "V_16", 22), - V23( "V_17", 23), - V24( "V_18", 24), - V25( "V_19", 25), - V26( "V_1A", 26), - V27( "V_1B", 27), - V28( "V_1C", 28), - V29( "V_1D", 29), - V30( "V_1E", 30), - V31( "V_1F", 31), - CYCOMM( "CYCOMM", 32), - V33( "V_21", 33), - V34( "V_22", 34), - V35( "V_23", 35), - V36( "V_24", 36), - V37( "V_25", 37), - V38( "V_26", 38), - V39( "V_27", 39), - EFRATOM( "EFRATOM", 40), - V41( "V_29", 41), - V42( "V_2A", 42), - V43( "V_2B", 43), - V44( "V_2C", 44), - V45( "V_2D", 45), - V46( "V_2E", 46), - V47( "V_2F", 47), - ERICSSON( "ERICSSON", 48), - V49( "V_31", 49), - V50( "V_32", 50), - V51( "V_33", 51), - V52( "V_34", 52), - V53( "V_35", 53), - V54( "V_36", 54), - V55( "V_37", 55), - DATRON( "DATRON", 56), - V57( "V_39", 57), - V58( "V_3A", 58), - V59( "V_3B", 59), - V60( "V_3C", 60), - V61( "V_3D", 61), - V62( "V_3E", 62), - V63( "V_3F", 63), - ICOM( "ICOM", 64), - V65( "V_41", 65), - V66( "V_42", 66), - V67( "V_43", 67), - V68( "V_44", 68), - V69( "V_45", 69), - V70( "V_46", 70), - V71( "V_47", 71), - GARMIN( "GARMIN", 72), - V73( "V_49", 73), - V74( "V_4A", 74), - V75( "V_4B", 75), - V76( "V_4C", 76), - V77( "V_4D", 77), - V78( "V_4E", 78), - V79( "V_4F", 79), - GTE( "GTE", 80), - V81( "V_51", 81), - V82( "V_52", 82), - V83( "V_53", 83), - V84( "V_54", 84), - IFR_SYSTEMS( "IFR SYSTEMS", 85), - V86( "V_56", 86), - V87( "V_57", 87), - V88( "V_58", 88), - V89( "V_59", 89), - V90( "V_5A", 90), - V91( "V_5B", 91), - V92( "V_5C", 92), - V93( "V_5D", 93), - V94( "V_5E", 94), - V95( "V_5F", 95), - GEC_MARCONI( "GEC-MARCONI", 96), - V97( "V_61", 97), - V98( "V_62", 98), - V99( "V_63", 99), - V100( "V_64", 100), - V101( "V_65", 101), - V102( "V_66", 102), - V103( "V_67", 103), - KENWOOD( "KENWOOD", 104), - V105( "V_69", 105), - V106( "V_6A", 106), - V107( "V_6B", 107), - V108( "V_6C", 108), - V109( "V_6D", 109), - V110( "V_6E", 110), - V111( "V_6F", 111), - GLENAYRE( "GLENAYRE ELECTRONICS", 112), - V113( "V_71", 113), - V114( "V_72", 114), - V115( "V_73", 115), - JAPAN_RADIO( "JAPAN RADIO CO", 116), - V117( "V_75", 117), - V118( "V_76", 118), - V119( "V_77", 119), - KOKUSAI( "KOKUSAI", 120), - V121( "V_79", 121), - V122( "V_7A", 122), - V123( "V_7B", 123), - MAXON( "MAXON", 124), - V125( "V_7D", 125), - V126( "V_7E", 126), - V127( "V_7F", 127), - MIDLAND( "MIDLAND", 128), - V129( "V_81", 129), - V130( "V_82", 130), - V131( "V_83", 131), - V132( "V_84", 132), - V133( "V_85", 133), - DANIELS( "DANIELS ELECTRONICS", 134), - V135( "V_87", 135), - V136( "V_88", 136), - V137( "V_89", 137), - V138( "V_8A", 138), - V139( "V_8B", 139), - V140( "V_8C", 140), - V141( "V_8D", 141), - V142( "V_8E", 142), - V143( "V_8F", 143), - MOTOROLA( "MOTOROLA", 144), - V145( "V_91", 145), - V146( "V_92", 146), - V147( "V_93", 147), - V148( "V_94", 148), - V149( "V_95", 149), - V150( "V_96", 150), - V151( "V_97", 151), - V152( "V_98", 152), - V153( "V_99", 153), - V154( "V_9A", 154), - V155( "V_9B", 155), - V156( "V_9C", 156), - V157( "V_9D", 157), - V158( "V_9E", 158), - V159( "V_9F", 159), - THALES( "THALES", 160), - V161( "V_A1", 161), - V162( "V_A2", 162), - V163( "V_A3", 163), - MACOM( "M/A-COM", 164), - V165( "V_A5", 165), - V166( "V_A6", 166), - V167( "V_A7", 167), - V168( "V_A8", 168), - V169( "V_A9", 169), - V170( "V_AA", 170), - V171( "V_AB", 171), - V172( "V_AC", 172), - V173( "V_AD", 173), - V174( "V_AE", 174), - V175( "V_AF", 175), - RATHEON( "RATHEON", 176), - V177( "V_B1", 177), - V178( "V_B2", 178), - V179( "V_B3", 179), - V180( "V_B4", 180), - V181( "V_B5", 181), - V182( "V_B6", 182), - V183( "V_B7", 183), - V184( "V_B8", 184), - V185( "V_B9", 185), - V186( "V_BA", 186), - V187( "V_BB", 187), - V188( "V_BC", 188), - V189( "V_BD", 189), - V190( "V_BE", 190), - V191( "V_BF", 191), - SEA( "SEA", 192), - V193( "V_C1", 193), - V194( "V_C2", 194), - V195( "V_C3", 195), - V196( "V_C4", 196), - V197( "V_C5", 197), - V198( "V_C6", 198), - V199( "V_C7", 199), - SECURICOR( "SECURICOR", 200), - V201( "V_C9", 201), - V202( "V_CA", 202), - V203( "V_CB", 203), - V204( "V_CC", 204), - V205( "V_CD", 205), - V206( "V_CE", 206), - V207( "V_CF", 207), - ADI( "ADI", 208), - V209( "V_D1", 209), - V210( "V_D2", 210), - V211( "V_D3", 211), - V212( "V_D4", 212), - V213( "V_D5", 213), - V214( "V_D6", 214), - V215( "V_D7", 215), - TAIT( "TAIT", 216), - V217( "V_D9", 217), - V218( "V_DA", 218), - V219( "V_DB", 219), - V220( "V_DC", 220), - V221( "V_DD", 221), - V222( "V_DE", 222), - V223( "V_DF", 223), - TELETEC( "TELETEC", 224), - V225( "V_E1", 225), - V226( "V_E2", 226), - V227( "V_E3", 227), - V228( "V_E4", 228), - V229( "V_E5", 229), - V230( "V_E6", 230), - V231( "V_E7", 231), - V232( "V_E8", 232), - V233( "V_E9", 233), - V234( "V_EA", 234), - V235( "V_EB", 235), - V236( "V_EC", 236), - V237( "V_ED", 237), - V238( "V_EE", 238), - V239( "V_EF", 239), - TRANSCRYPT( "TRANSCRYPT", 240), - V241( "V_F1", 241), - V242( "V_F2", 242), - V243( "V_F3", 243), - V244( "V_F4", 244), - V245( "V_F5", 245), - V246( "V_F6", 246), - V247( "V_F7", 247), - V248( "V_F8", 248), - V249( "V_F9", 249), - V250( "V_FA", 250), - V251( "V_FB", 251), - V252( "V_FC", 252), - V253( "V_FD", 253), - V254( "V_FE", 254), - V255( "V_FF", 255), - VUNK( "UNKN", -1 ); + STANDARD( "STANDARD", "STANDARD", 0), + V1( "VENDOR01", "V_01", 1), + V2( "VENDOR02", "V_02", 2), + V3( "VENDOR03", "V_03", 3), + V4( "VENDOR04", "V_04", 4), + V5( "VENDOR05", "V_05", 5), + V6( "VENDOR06", "V_06", 6), + V7( "VENDOR07", "V_07", 7), + V8( "VENDOR08", "V_08", 8), + V9( "VENDOR09", "V_09", 9), + V10( "VENDOR0A", "V_0A", 10), + V11( "VENDOR0B", "V_0B", 11), + V12( "VENDOR0C", "V_0C", 12), + V13( "VENDOR0D", "V_0D", 13), + V14( "VENDOR0E", "V_0E", 14), + V15( "VENDOR0F", "V_0F", 15), + RELM( "RELM BK ", "RELM/BK RADIO", 16), + V17( "VENDOR11", "V_11", 17), + V18( "VENDOR12", "V_12", 18), + V19( "VENDOR13", "V_13", 19), + V20( "VENDOR14", "V_14", 20), + V21( "VENDOR15", "V_15", 21), + V22( "VENDOR16", "V_16", 22), + V23( "VENDOR17", "V_17", 23), + V24( "VENDOR18", "V_18", 24), + V25( "VENDOR19", "V_19", 25), + V26( "VENDOR1A", "V_1A", 26), + V27( "VENDOR1B", "V_1B", 27), + V28( "VENDOR1C", "V_1C", 28), + V29( "VENDOR1D", "V_1D", 29), + V30( "VENDOR1E", "V_1E", 30), + V31( "VENDOR1F", "V_1F", 31), + CYCOMM( "CYCOMM ", "CYCOMM", 32), + V33( "VENDOR21", "V_21", 33), + V34( "VENDOR22", "V_22", 34), + V35( "VENDOR23", "V_23", 35), + V36( "VENDOR24", "V_24", 36), + V37( "VENDOR25", "V_25", 37), + V38( "VENDOR26", "V_26", 38), + V39( "VENDOR27", "V_27", 39), + EFRATOM( "EFRATOM ", "EFRATOM", 40), + V41( "VENDOR29", "V_29", 41), + V42( "VENDOR2A", "V_2A", 42), + V43( "VENDOR2B", "V_2B", 43), + V44( "VENDOR2C", "V_2C", 44), + V45( "VENDOR2D", "V_2D", 45), + V46( "VENDOR2E", "V_2E", 46), + V47( "VENDOR2F", "V_2F", 47), + ERICSSON( "ERICSSON", "ERICSSON", 48), + V49( "VENDOR31", "V_31", 49), + V50( "VENDOR32", "V_32", 50), + V51( "VENDOR33", "V_33", 51), + V52( "VENDOR34", "V_34", 52), + V53( "VENDOR35", "V_35", 53), + V54( "VENDOR36", "V_36", 54), + V55( "VENDOR37", "V_37", 55), + DATRON( "DATRON ", "DATRON", 56), + V57( "VENDOR39", "V_39", 57), + V58( "VENDOR3A", "V_3A", 58), + V59( "VENDOR3B", "V_3B", 59), + V60( "VENDOR3C", "V_3C", 60), + V61( "VENDOR3D", "V_3D", 61), + V62( "VENDOR3E", "V_3E", 62), + V63( "VENDOR3F", "V_3F", 63), + ICOM( "ICOM ", "ICOM", 64), + V65( "VENDOR41", "V_41", 65), + V66( "VENDOR42", "V_42", 66), + V67( "VENDOR43", "V_43", 67), + V68( "VENDOR44", "V_44", 68), + V69( "VENDOR45", "V_45", 69), + V70( "VENDOR46", "V_46", 70), + V71( "VENDOR47", "V_47", 71), + GARMIN( "GARMIN ", "GARMIN", 72), + V73( "VENDOR49", "V_49", 73), + V74( "VENDOR4A", "V_4A", 74), + V75( "VENDOR4B", "V_4B", 75), + V76( "VENDOR4C", "V_4C", 76), + V77( "VENDOR4D", "V_4D", 77), + V78( "VENDOR4E", "V_4E", 78), + V79( "VENDOR4F", "V_4F", 79), + GTE( "GTE ", "GTE", 80), + V81( "VENDOR51", "V_51", 81), + V82( "VENDOR52", "V_52", 82), + V83( "VENDOR53", "V_53", 83), + V84( "VENDOR54", "V_54", 84), + IFR_SYSTEMS( "IFR SYST", "IFR SYSTEMS", 85), + V86( "VENDOR54", "V_56", 86), + V87( "VENDOR57", "V_57", 87), + V88( "VENDOR58", "V_58", 88), + V89( "VENDOR59", "V_59", 89), + V90( "VENDOR5A", "V_5A", 90), + V91( "VENDOR5B", "V_5B", 91), + V92( "VENDOR5C", "V_5C", 92), + V93( "VENDOR5D", "V_5D", 93), + V94( "VENDOR5E", "V_5E", 94), + V95( "VENDOR5F", "V_5F", 95), + GEC_MARCONI( "MARCONI ", "GEC-MARCONI", 96), + V97( "VENDOR61", "V_61", 97), + V98( "VENDOR62", "V_62", 98), + V99( "VENDOR63", "V_63", 99), + V100( "VENDOR64", "V_64", 100), + V101( "VENDOR65", "V_65", 101), + V102( "VENDOR66", "V_66", 102), + V103( "VENDOR67", "V_67", 103), + KENWOOD( "KENWOOD ", "KENWOOD", 104), + V105( "VENDOR69", "V_69", 105), + V106( "VENDOR6A", "V_6A", 106), + V107( "VENDOR6B", "V_6B", 107), + V108( "VENDOR6C", "V_6C", 108), + V109( "VENDOR6D", "V_6D", 109), + V110( "VENDOR6E", "V_6E", 110), + V111( "VENDOR6F", "V_6F", 111), + GLENAYRE( "GLENAYRE", "GLENAYRE ELECTRONICS", 112), + V113( "VENDOR71", "V_71", 113), + V114( "VENDOR72", "V_72", 114), + V115( "VENDOR73", "V_73", 115), + JAPAN_RADIO( "JAPRADCO", "JAPAN RADIO CO", 116), + V117( "VENDOR75", "V_75", 117), + V118( "VENDOR76", "V_76", 118), + V119( "VENDOR77", "V_77", 119), + KOKUSAI( "KOKUSAI ", "KOKUSAI", 120), + V121( "VENDOR79", "V_79", 121), + V122( "VENDOR7A", "V_7A", 122), + V123( "VENDOR7B", "V_7B", 123), + MAXON( "MAXON ", "MAXON", 124), + V125( "VENDOR7D", "V_7D", 125), + V126( "VENDOR7E", "V_7E", 126), + V127( "VENDOR7F", "V_7F", 127), + MIDLAND( "MIDLAND ", "MIDLAND", 128), + V129( "VENDOR81", "V_81", 129), + V130( "VENDOR82", "V_82", 130), + V131( "VENDOR83", "V_83", 131), + V132( "VENDOR84", "V_84", 132), + V133( "VENDOR85", "V_85", 133), + DANIELS( "DANIELS ", "DANIELS ELECTRONICS", 134), + V135( "VENDOR87", "V_87", 135), + V136( "VENDOR88", "V_88", 136), + V137( "VENDOR89", "V_89", 137), + V138( "VENDOR8A", "V_8A", 138), + V139( "VENDOR8B", "V_8B", 139), + V140( "VENDOR8C", "V_8C", 140), + V141( "VENDOR8D", "V_8D", 141), + V142( "VENDOR8E", "V_8E", 142), + V143( "VENDOR8F", "V_8F", 143), + MOTOROLA( "MOTOROLA", "MOTOROLA", 144), + V145( "VENDOR91", "V_91", 145), + V146( "VENDOR92", "V_92", 146), + V147( "VENDOR93", "V_93", 147), + V148( "VENDOR94", "V_94", 148), + V149( "VENDOR95", "V_95", 149), + V150( "VENDOR96", "V_96", 150), + V151( "VENDOR97", "V_97", 151), + V152( "VENDOR98", "V_98", 152), + V153( "VENDOR99", "V_99", 153), + V154( "VENDOR9A", "V_9A", 154), + V155( "VENDOR9B", "V_9B", 155), + V156( "VENDOR9C", "V_9C", 156), + V157( "VENDOR9D", "V_9D", 157), + V158( "VENDOR9E", "V_9E", 158), + V159( "VENDOR9F", "V_9F", 159), + THALES( "THALES ", "THALES", 160), + V161( "VENDORA1", "V_A1", 161), + V162( "VENDORA2", "V_A2", 162), + V163( "VENDORA3", "V_A3", 163), + MACOM( "M/A-COM ", "M/A-COM", 164), + V165( "VENDORA5", "V_A5", 165), + V166( "VENDORA6", "V_A6", 166), + V167( "VENDORA7", "V_A7", 167), + V168( "VENDORA8", "V_A8", 168), + V169( "VENDORA9", "V_A9", 169), + V170( "VENDORAA", "V_AA", 170), + V171( "VENDORAB", "V_AB", 171), + V172( "VENDORAC", "V_AC", 172), + V173( "VENDORAD", "V_AD", 173), + V174( "VENDORAE", "V_AE", 174), + V175( "VENDORAF", "V_AF", 175), + RATHEON( "RATHEON ", "RATHEON", 176), + V177( "VENDORB1", "V_B1", 177), + V178( "VENDORB2", "V_B2", 178), + V179( "VENDORB3", "V_B3", 179), + V180( "VENDORB4", "V_B4", 180), + V181( "VENDORB5", "V_B5", 181), + V182( "VENDORB6", "V_B6", 182), + V183( "VENDORB7", "V_B7", 183), + V184( "VENDORB8", "V_B8", 184), + V185( "VENDORB9", "V_B9", 185), + V186( "VENDORBA", "V_BA", 186), + V187( "VENDORBB", "V_BB", 187), + V188( "VENDORBC", "V_BC", 188), + V189( "VENDORBD", "V_BD", 189), + V190( "VENDORBE", "V_BE", 190), + V191( "VENDORBF", "V_BF", 191), + SEA( "SEA ", "SEA", 192), + V193( "VENDORC1", "V_C1", 193), + V194( "VENDORC2", "V_C2", 194), + V195( "VENDORC3", "V_C3", 195), + V196( "VENDORC4", "V_C4", 196), + V197( "VENDORC5", "V_C5", 197), + V198( "VENDORC6", "V_C6", 198), + V199( "VENDORC7", "V_C7", 199), + SECURICOR( "SECURICO", "SECURICOR", 200), + V201( "VENDORC9", "V_C9", 201), + V202( "VENDORCA", "V_CA", 202), + V203( "VENDORCB", "V_CB", 203), + V204( "VENDORCC", "V_CC", 204), + V205( "VENDORCD", "V_CD", 205), + V206( "VENDORCE", "V_CE", 206), + V207( "VENDORCF", "V_CF", 207), + ADI( "ADI ", "ADI", 208), + V209( "VENDORD1", "V_D1", 209), + V210( "VENDORD2", "V_D2", 210), + V211( "VENDORD3", "V_D3", 211), + V212( "VENDORD4", "V_D4", 212), + V213( "VENDORD5", "V_D5", 213), + V214( "VENDORD6", "V_D6", 214), + V215( "VENDORD7", "V_D7", 215), + TAIT( "TAIT ", "TAIT", 216), + V217( "VENDORD9", "V_D9", 217), + V218( "VENDORDA", "V_DA", 218), + V219( "VENDORDB", "V_DB", 219), + V220( "VENDORDC", "V_DC", 220), + V221( "VENDORDD", "V_DD", 221), + V222( "VENDORDE", "V_DE", 222), + V223( "VENDORDF", "V_DF", 223), + TELETEC( "TELETEC ", "TELETEC", 224), + V225( "VENDORE1", "V_E1", 225), + V226( "VENDORE2", "V_E2", 226), + V227( "VENDORE3", "V_E3", 227), + V228( "VENDORE4", "V_E4", 228), + V229( "VENDORE5", "V_E5", 229), + V230( "VENDORE6", "V_E6", 230), + V231( "VENDORE7", "V_E7", 231), + V232( "VENDORE8", "V_E8", 232), + V233( "VENDORE9", "V_E9", 233), + V234( "VENDOREA", "V_EA", 234), + V235( "VENDOREB", "V_EB", 235), + V236( "VENDOREC", "V_EC", 236), + V237( "VENDORED", "V_ED", 237), + V238( "VENDOREE", "V_EE", 238), + V239( "VENDOREF", "V_EF", 239), + TRANSCRYPT( "TRANSCRPT", "TRANSCRYPT", 240), + V241( "VENDORF1", "V_F1", 241), + V242( "VENDORF2", "V_F2", 242), + V243( "VENDORF3", "V_F3", 243), + V244( "VENDORF4", "V_F4", 244), + V245( "VENDORF5", "V_F5", 245), + V246( "VENDORF6", "V_F6", 246), + V247( "VENDORF7", "V_F7", 247), + V248( "VENDORF8", "V_F8", 248), + V249( "VENDORF9", "V_F9", 249), + V250( "VENDORFA", "V_FA", 250), + V251( "VENDORFB", "V_FB", 251), + V252( "VENDORFC", "V_FC", 252), + V253( "VENDORFD", "V_FD", 253), + V254( "VENDORFE", "V_FE", 254), + V255( "VENDORFF", "V_FF", 255), + VUNK( "UNKNOWN ", "UNKN", -1 ); private String mLabel; + private String mDescription; private int mValue; - private Vendor( String label, int value ) + private Vendor( String label, String description, int value ) { mLabel = label; + mDescription = description; mValue = value; } @@ -274,6 +276,11 @@ public enum Vendor return mLabel; } + public String getDescription() + { + return mDescription; + } + public int getValue() { return mValue; diff --git a/src/dsp/fsk/C4FMSlicer.java b/src/dsp/fsk/C4FMSlicer.java index 5f2b4f23..199c4ce5 100644 --- a/src/dsp/fsk/C4FMSlicer.java +++ b/src/dsp/fsk/C4FMSlicer.java @@ -15,7 +15,7 @@ public class C4FMSlicer implements RealSampleListener { private static final float THRESHOLD = 2.0f; - private Broadcaster mBroadcaster = new Broadcaster(); + private Broadcaster mBroadcaster = new Broadcaster(); /** * Primary method for receiving output from the C4FMSymbolFilter. Slices @@ -26,26 +26,26 @@ public class C4FMSlicer implements RealSampleListener { if( sample > THRESHOLD ) { - dispatch( C4FMSymbol.SYMBOL_PLUS_3 ); + dispatch( Dibit.D01_PLUS_3 ); } else if( sample > 0 ) { - dispatch( C4FMSymbol.SYMBOL_PLUS_1 ); + dispatch( Dibit.D00_PLUS_1 ); } else if( sample > -THRESHOLD ) { - dispatch( C4FMSymbol.SYMBOL_MINUS_1 ); + dispatch( Dibit.D10_MINUS_1 ); } else { - dispatch( C4FMSymbol.SYMBOL_MINUS_3 ); + dispatch( Dibit.D11_MINUS_3 ); } } /** * Dispatches the symbol decision to any registered listeners */ - private void dispatch( C4FMSymbol symbol ) + private void dispatch( Dibit symbol ) { mBroadcaster.receive( symbol ); } @@ -54,7 +54,7 @@ public class C4FMSlicer implements RealSampleListener * Registers the listener to receive the normal (non-inverted) C4FM symbol * stream. */ - public void addListener( Listener listener ) + public void addListener( Listener listener ) { mBroadcaster.addListener( listener ); } @@ -62,7 +62,7 @@ public class C4FMSlicer implements RealSampleListener /** * Removes the listener */ - public void removeListener( Listener listener ) + public void removeListener( Listener listener ) { mBroadcaster.removeListener( listener ); } diff --git a/src/dsp/fsk/C4FMSymbol.java b/src/dsp/fsk/C4FMSymbol.java deleted file mode 100644 index 12030083..00000000 --- a/src/dsp/fsk/C4FMSymbol.java +++ /dev/null @@ -1,44 +0,0 @@ -package dsp.fsk; - -public enum C4FMSymbol -{ - SYMBOL_PLUS_3( false, true ), - SYMBOL_PLUS_1( false, false ), - SYMBOL_MINUS_1( true, false ), - SYMBOL_MINUS_3( true, true ); - - private boolean mBit1; - private boolean mBit2; - - private C4FMSymbol( boolean bit1, boolean bit2 ) - { - mBit1 = bit1; - mBit2 = bit2; - } - - public boolean getBit1() - { - return mBit1; - } - - public boolean getBit2() - { - return mBit2; - } - - public static C4FMSymbol inverted( C4FMSymbol symbol ) - { - switch( symbol ) - { - case SYMBOL_MINUS_1: - return SYMBOL_MINUS_3; - case SYMBOL_MINUS_3: - return SYMBOL_PLUS_3; - case SYMBOL_PLUS_1: - return SYMBOL_MINUS_1; - case SYMBOL_PLUS_3: - default: - return SYMBOL_PLUS_1; - } - } -} diff --git a/src/dsp/fsk/Dibit.java b/src/dsp/fsk/Dibit.java new file mode 100644 index 00000000..21e6537f --- /dev/null +++ b/src/dsp/fsk/Dibit.java @@ -0,0 +1,58 @@ +package dsp.fsk; + +public enum Dibit +{ + D01_PLUS_3( false, true, 1, 4 ), + D00_PLUS_1( false, false, 0, 0 ), + D10_MINUS_1( true, false, 2, 8 ), + D11_MINUS_3( true, true, 3, 12 ); + + private boolean mBit1; + private boolean mBit2; + private int mLowValue; + private int mHighValue; + + private Dibit( boolean bit1, boolean bit2, int lowValue, int highValue ) + { + mBit1 = bit1; + mBit2 = bit2; + mLowValue = lowValue; + mHighValue = highValue; + } + + public boolean getBit1() + { + return mBit1; + } + + public boolean getBit2() + { + return mBit2; + } + + public int getLowValue() + { + return mLowValue; + } + + public int getHighValue() + { + return mHighValue; + } + + public static Dibit inverted( Dibit symbol ) + { + switch( symbol ) + { + case D10_MINUS_1: + return D11_MINUS_3; + case D11_MINUS_3: + return D01_PLUS_3; + case D00_PLUS_1: + return D10_MINUS_1; + case D01_PLUS_3: + default: + return D00_PLUS_1; + } + } +} diff --git a/src/dsp/fsk/P25MessageFramer.java b/src/dsp/fsk/P25MessageFramer.java index de446f7a..b681a10e 100644 --- a/src/dsp/fsk/P25MessageFramer.java +++ b/src/dsp/fsk/P25MessageFramer.java @@ -20,20 +20,17 @@ import decode.p25.message.tsbk.TSBKMessage; import decode.p25.message.tsbk.TSBKMessageFactory; import decode.p25.reference.DataUnitID; -public class P25MessageFramer implements Listener +public class P25MessageFramer implements Listener { private final static Logger mLog = LoggerFactory.getLogger( P25MessageFramer.class ); - private static final int[] STATUS_BITS = - new int[] { 22,92,162,232,302,372,442,512,582,652,722,792,862,932 }; - private ArrayList mAssemblers = new ArrayList(); public static final int TSBK_BEGIN = 64; public static final int TSBK_END = 260; - public static final int TSBK_DECODED_END = 162; + public static final int TSBK_DECODED_END = 160; private Listener mListener; private AliasList mAliasList; @@ -82,18 +79,16 @@ public class P25MessageFramer implements Listener } @Override - public void receive( C4FMSymbol symbol ) + public void receive( Dibit symbol ) { - C4FMSymbol correctedSymbol = symbol; - - mMatcher.receive( correctedSymbol.getBit1() ); - mMatcher.receive( correctedSymbol.getBit2() ); + mMatcher.receive( symbol.getBit1() ); + mMatcher.receive( symbol.getBit2() ); for( P25MessageAssembler assembler: mAssemblers ) { if( assembler.isActive() ) { - assembler.receive( correctedSymbol ); + assembler.receive( symbol ); if( assembler.complete() ) { @@ -120,7 +115,7 @@ public class P25MessageFramer implements Listener if( !found ) { - mLog.debug( "no inactive C4FM message assemblers available" ); + mLog.debug( "no inactive P25 message assemblers available" ); } } } @@ -137,7 +132,9 @@ public class P25MessageFramer implements Listener private class P25MessageAssembler { - private int mStatusIndicatorPointer = 0; + /* Starting position of the status symbol counter is 24 symbols to + * account for the 48-bit sync pattern */ + private int mStatusSymbolPointer = 24; private BitSetBuffer mMessage; private int mMessageLength; private boolean mComplete = false; @@ -151,21 +148,22 @@ public class P25MessageFramer implements Listener reset(); } - public void receive( C4FMSymbol symbol ) + public void receive( Dibit dibit ) { if( mActive ) { - /* Throw away status bits that are injected every 70 bits */ - if( mMessage.pointer() == STATUS_BITS[ mStatusIndicatorPointer ] ) + if( mStatusSymbolPointer == 35 ) { - mStatusIndicatorPointer++; + mStatusSymbolPointer = 0; } else { + mStatusSymbolPointer++; + try { - mMessage.add( symbol.getBit1() ); - mMessage.add( symbol.getBit2() ); + mMessage.add( dibit.getBit1() ); + mMessage.add( dibit.getBit2() ); } catch( BitSetFullException e ) { @@ -186,7 +184,7 @@ public class P25MessageFramer implements Listener mDUID = DataUnitID.NID; mMessage.setSize( mDUID.getMessageLength() ); mMessage.clear(); - mStatusIndicatorPointer = 0; + mStatusSymbolPointer = 24; mComplete = false; mActive = false; } @@ -268,13 +266,20 @@ public class P25MessageFramer implements Listener dispatch( new P25Message( mMessage.copy(), mDUID, mAliasList ) ); break; case TSBK1: +// mLog.debug( "NEW: " + mMessage.toString() ); + /* Remove interleaving */ P25Interleave.deinterleave( mMessage, TSBK_BEGIN, TSBK_END ); + +// mLog.debug( "DEI: " + mMessage.toString() ); /* Remove trellis encoding */ mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END ); +// mLog.debug( "DEC: " + mMessage.toString() ); + BitSetBuffer tsbkBuffer1 = mMessage.copy(); + tsbkBuffer1.setSize( TSBK_DECODED_END ); TSBKMessage tsbkMessage1 = TSBKMessageFactory.getMessage( tsbkBuffer1, DataUnitID.TSBK1, mAliasList ); @@ -299,6 +304,7 @@ public class P25MessageFramer implements Listener mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END ); BitSetBuffer tsbkBuffer2 = mMessage.copy(); + tsbkBuffer2.setSize( TSBK_DECODED_END ); TSBKMessage tsbkMessage2 = TSBKMessageFactory.getMessage( tsbkBuffer2, DataUnitID.TSBK2, mAliasList ); @@ -324,6 +330,7 @@ public class P25MessageFramer implements Listener mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END ); BitSetBuffer tsbkBuffer3 = mMessage.copy(); + tsbkBuffer3.setSize( TSBK_DECODED_END ); TSBKMessage tsbkMessage3 = TSBKMessageFactory.getMessage( tsbkBuffer3, DataUnitID.TSBK3, mAliasList );