P25 work in progress

This commit is contained in:
dennis.sheirer
2014-11-22 16:13:44 +00:00
parent 960de375bc
commit 1660f13633
44 changed files with 788 additions and 656 deletions

View File

@@ -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() );
}
}

View File

@@ -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<Message>
{
@@ -23,6 +24,13 @@ public class P25MessageProcessor implements Listener<Message>
@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() );
}
}
}

View File

@@ -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<ConstellationNode> mConstellationNodes =
new ArrayList<ConstellationNode>();
@@ -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!" );
}
}

View File

@@ -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

View File

@@ -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( " " );

View File

@@ -34,7 +34,7 @@ public abstract class GroupChannelGrant extends ChannelGrant
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
if( isEmergency() )
{

View File

@@ -26,7 +26,7 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
if( isEmergency() )
{

View File

@@ -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() );

View File

@@ -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();

View File

@@ -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,

View File

@@ -24,7 +24,7 @@ public abstract class UnitChannelGrant extends ChannelGrant
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
if( isEmergency() )
{

View File

@@ -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() );

View File

@@ -40,7 +40,7 @@ public class AdjacentStatusBroadcast extends TSBKMessage
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
sb.append( " LRA:" + getLocationRegistrationArea() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -36,7 +36,7 @@ public class NetworkStatusBroadcast extends TSBKMessage
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
sb.append( " LRA:" + getLocationRegistrationArea() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -37,7 +37,7 @@ public class RFSSStatusBroadcast extends TSBKMessage
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
sb.append( " LRA:" + getLocationRegistrationArea() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -36,7 +36,7 @@ public class SecondaryControlChannelBroadcast extends TSBKMessage
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
sb.append( " RFSS:" + getRFSS() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -35,7 +35,7 @@ public class SystemServiceBroadcast extends TSBKMessage
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
sb.append( " SERVICES AVAILABLE " );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -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() );

View File

@@ -22,7 +22,7 @@ public class TelephoneInterconnectVoiceChannelGrant extends UnitChannelGrant
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getMessageStub() );
if( isEmergency() )
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -15,7 +15,7 @@ public class C4FMSlicer implements RealSampleListener
{
private static final float THRESHOLD = 2.0f;
private Broadcaster<C4FMSymbol> mBroadcaster = new Broadcaster<C4FMSymbol>();
private Broadcaster<Dibit> mBroadcaster = new Broadcaster<Dibit>();
/**
* 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<C4FMSymbol> listener )
public void addListener( Listener<Dibit> listener )
{
mBroadcaster.addListener( listener );
}
@@ -62,7 +62,7 @@ public class C4FMSlicer implements RealSampleListener
/**
* Removes the listener
*/
public void removeListener( Listener<C4FMSymbol> listener )
public void removeListener( Listener<Dibit> listener )
{
mBroadcaster.removeListener( listener );
}

View File

@@ -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;
}
}
}

58
src/dsp/fsk/Dibit.java Normal file
View File

@@ -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;
}
}
}

View File

@@ -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<C4FMSymbol>
public class P25MessageFramer implements Listener<Dibit>
{
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<P25MessageAssembler> mAssemblers =
new ArrayList<P25MessageAssembler>();
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<Message> mListener;
private AliasList mAliasList;
@@ -82,18 +79,16 @@ public class P25MessageFramer implements Listener<C4FMSymbol>
}
@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<C4FMSymbol>
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<C4FMSymbol>
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<C4FMSymbol>
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<C4FMSymbol>
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<C4FMSymbol>
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<C4FMSymbol>
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<C4FMSymbol>
mHalfRate.decode( mMessage, TSBK_BEGIN, TSBK_END );
BitSetBuffer tsbkBuffer3 = mMessage.copy();
tsbkBuffer3.setSize( TSBK_DECODED_END );
TSBKMessage tsbkMessage3 = TSBKMessageFactory.getMessage(
tsbkBuffer3, DataUnitID.TSBK3, mAliasList );