mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
P25 - adds SNDCP context management and data packet parsing for IPV4 and UDP/IP packets to include IP addresses and data payload bytes.
This commit is contained in:
@@ -37,12 +37,14 @@ import decode.Decoder;
|
||||
import decode.DecoderType;
|
||||
import dsp.filter.ComplexFIRFilter;
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.FloatFIRFilter;
|
||||
import dsp.filter.Window.WindowType;
|
||||
import dsp.fsk.C4FMSlicer;
|
||||
import dsp.fsk.C4FMSymbolFilter;
|
||||
import dsp.fsk.P25MessageFramer;
|
||||
import dsp.gain.DirectGainControl;
|
||||
import dsp.nbfm.FMDiscriminator;
|
||||
import dsp.nbfm.FilteringNBFMDemodulator;
|
||||
|
||||
public class P25Decoder extends Decoder
|
||||
implements DirectFrequencyController, Instrumentable
|
||||
@@ -57,9 +59,11 @@ public class P25Decoder extends Decoder
|
||||
private List<Tap> mAvailableTaps;
|
||||
|
||||
private ComplexFIRFilter mBasebandFilter = new ComplexFIRFilter(
|
||||
FilterFactory.getLowPass( 48000, 5000, 31, WindowType.HAMMING ), 1.0 );
|
||||
|
||||
FilterFactory.getLowPass( 48000, 6000, 7000, 48, WindowType.HANNING, true ), 1.0 );
|
||||
private FMDiscriminator mDemodulator = new FMDiscriminator( 1 );
|
||||
private FloatFIRFilter mAudioFilter = new FloatFIRFilter(
|
||||
FilterFactory.getLowPass( 48000, 3000, 4000, 48, WindowType.HAMMING, true ), 1.0 );
|
||||
|
||||
private DirectGainControl mGainControl =
|
||||
new DirectGainControl( 15.0f, 0.1f, 25.0f, 0.3f );
|
||||
private C4FMSymbolFilter mSymbolFilter;
|
||||
@@ -97,7 +101,8 @@ public class P25Decoder extends Decoder
|
||||
mDemodulator.setListener( getRealReceiver() );
|
||||
}
|
||||
|
||||
addRealSampleListener( mGainControl );
|
||||
addRealSampleListener( mAudioFilter );
|
||||
mAudioFilter.setListener( mGainControl );
|
||||
mGainControl.setListener( mSymbolFilter );
|
||||
|
||||
mSymbolFilter.setListener( mSlicer );
|
||||
|
||||
@@ -41,6 +41,11 @@ public class P25Message extends Message
|
||||
mAliasList = aliasList;
|
||||
}
|
||||
|
||||
public CRC[] getCRCResults()
|
||||
{
|
||||
return mCRC;
|
||||
}
|
||||
|
||||
public BitSetBuffer getSourceMessage()
|
||||
{
|
||||
return mMessage;
|
||||
|
||||
@@ -106,6 +106,11 @@ public class PDUMessage extends P25Message
|
||||
return mMessage.get( PACKET_DIRECTION_INDICATOR ) ? "OSP" : "ISP";
|
||||
}
|
||||
|
||||
public boolean isOutbound()
|
||||
{
|
||||
return mMessage.get( PACKET_DIRECTION_INDICATOR );
|
||||
}
|
||||
|
||||
public PDUFormat getFormat()
|
||||
{
|
||||
return PDUFormat.fromValue( mMessage.getInt( FORMAT ) );
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package decode.p25.message.pdu;
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.pdu.PDUMessage;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
import decode.p25.reference.PDUType;
|
||||
import decode.p25.reference.Vendor;
|
||||
import edac.CRC;
|
||||
import edac.CRCP25;
|
||||
@@ -19,17 +21,28 @@ public class PDUConfirmedMessage extends PDUMessage
|
||||
public static final int[] PACKET_SEQUENCE_NUMBER = { 129,130,131 };
|
||||
public static final int FINAL_FRAGMENT_FLAG = 132;
|
||||
public static final int[] FRAGMENT_SEQUENCE_NUMBER = { 133,134,135 };
|
||||
public static final int PACKET_DATA_START = 176;
|
||||
public static final int[] PDU_TYPE = { 176,177,178,179 };
|
||||
|
||||
public PDUConfirmedMessage( BitSetBuffer message, DataUnitID duid,
|
||||
AliasList aliasList )
|
||||
public PDUConfirmedMessage( BitSetBuffer message, AliasList aliasList )
|
||||
{
|
||||
super( message, duid, aliasList );
|
||||
super( message, DataUnitID.PDUC, aliasList );
|
||||
|
||||
checkCRC();
|
||||
|
||||
mLog.debug( toString() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to support subclassing of this message. Initial construction
|
||||
* of the message enables CRC checks to be calculated and message type to
|
||||
* be inspected so that we can construct an accurate subclass message,
|
||||
* without having to recalculate CRC checksums.
|
||||
*/
|
||||
protected PDUConfirmedMessage( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message.getSourceMessage(), DataUnitID.PDUC, message.getAliasList() );
|
||||
mCRC = message.getCRCResults();
|
||||
|
||||
mLog.debug( toString() );
|
||||
}
|
||||
|
||||
private void checkCRC()
|
||||
{
|
||||
@@ -60,6 +73,7 @@ public class PDUConfirmedMessage extends PDUMessage
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "[" + this.getClass() + "]" );
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " " );
|
||||
@@ -100,15 +114,25 @@ public class PDUConfirmedMessage extends PDUMessage
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( " " );
|
||||
sb.append( getPacket() );
|
||||
|
||||
sb.append( " BLOCKS:" );
|
||||
sb.append( getBlocksToFollowCount() );
|
||||
|
||||
sb.append( " " );
|
||||
sb.append( mMessage.toString() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Packet Data Unit Type
|
||||
*/
|
||||
public PDUType getPDUType()
|
||||
{
|
||||
return PDUType.fromValue( mMessage.getInt( PDU_TYPE ), isOutbound() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Number of bytes/octets contained in the message, exclusive of the data
|
||||
* header.
|
||||
@@ -179,66 +203,8 @@ public class PDUConfirmedMessage extends PDUMessage
|
||||
return mMessage.getInt( FRAGMENT_SEQUENCE_NUMBER );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hex string representation of the packet data, including packet header
|
||||
* data if present.
|
||||
*/
|
||||
public String getPacket()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int dataHeaderOffset = getDataHeaderOffset();
|
||||
|
||||
if( dataHeaderOffset > 0 )
|
||||
{
|
||||
sb.append( "HDR:" );
|
||||
|
||||
for( int x = 0; x < dataHeaderOffset; x++ )
|
||||
{
|
||||
sb.append( getPacketOctet( x ) );
|
||||
}
|
||||
|
||||
sb.append( " " );
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
|
||||
/* Append octets inserting a space between each 32-bit value */
|
||||
for( int x = 0; x < getOctetCount(); x++ )
|
||||
{
|
||||
sb.append( getPacketOctet( x + dataHeaderOffset ) );
|
||||
|
||||
counter++;
|
||||
|
||||
if( counter >= 4 )
|
||||
{
|
||||
sb.append( " " );
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the octet identified by the 0-indexed 'octet' argument location.
|
||||
* If there is a Data Header Offset, the 0 index points to the first octet
|
||||
* of the data header. Otherwise, the 0 index points to the first octet
|
||||
* of the packet. You must account for the data header offset when
|
||||
* specifying the octet.
|
||||
*/
|
||||
public String getPacketOctet( int octet )
|
||||
{
|
||||
int block = (int)( octet / 16 );
|
||||
int offset = octet % 16;
|
||||
|
||||
int start = PACKET_DATA_START + ( block * 144 ) + ( offset * 8 );
|
||||
|
||||
return mMessage.getHex( start, start + 7, 2 );
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " " + mMessage.toString();
|
||||
return getMessage();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class PDUConfirmedMessageFactory
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( PDUConfirmedMessage.class );
|
||||
|
||||
public static PDUConfirmedMessage getMessage( PDUConfirmedMessage message )
|
||||
{
|
||||
switch( message.getServiceAccessPoint() )
|
||||
{
|
||||
case ADDRESS_RESOLUTION_PROTOCOL:
|
||||
break;
|
||||
case CHANNEL_REASSIGNMENT:
|
||||
break;
|
||||
case CIRCUIT_DATA:
|
||||
break;
|
||||
case CIRCUIT_DATA_CONTROL:
|
||||
break;
|
||||
case ENCRYPTED_KEY_MANAGEMENT_MESSAGE:
|
||||
break;
|
||||
case ENCRYPTED_TRUNKING_CONTROL:
|
||||
break;
|
||||
case ENCRYPTED_USER_DATA:
|
||||
break;
|
||||
case EXTENDED_ADDRESS:
|
||||
break;
|
||||
case MR_CONFIGURATION:
|
||||
break;
|
||||
case MR_LOOPBACK:
|
||||
break;
|
||||
case MR_OUT_OF_SERVICE:
|
||||
break;
|
||||
case MR_PAGING:
|
||||
break;
|
||||
case MR_STATISTICS:
|
||||
break;
|
||||
case PACKET_DATA:
|
||||
break;
|
||||
case REGISTRATION_AND_AUTHORIZATION:
|
||||
break;
|
||||
/* Deliberate fall-through */
|
||||
case SNDCP_PACKET_DATA_CONTROL:
|
||||
case UNENCRYPTED_USER_DATA:
|
||||
switch( message.getPDUType() )
|
||||
{
|
||||
case SN_ACTIVATE_TDS_CONTEXT_ACCEPT:
|
||||
return new SNDCPActivateTDSContextAccept( message );
|
||||
case SN_ACTIVATE_TDS_CONTEXT_REJECT:
|
||||
return new SNDCPActivateTDSContextReject( message );
|
||||
case SN_ACTIVATE_TDS_CONTEXT_REQUEST:
|
||||
return new SNDCPActivateTDSContextRequest( message );
|
||||
case SN_DEACTIVATE_TDS_CONTEXT_ACCEPT:
|
||||
case SN_DEACTIVATE_TDS_CONTEXT_REQUEST:
|
||||
return new SNDCPDeactivateTDSContext( message );
|
||||
case SN_RF_CONFIRMED_DATA:
|
||||
return new SNDCPUserData( message );
|
||||
case SN_RF_UNCONFIRMED_DATA:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SYSTEM_CONFIGURATION:
|
||||
break;
|
||||
case UNENCRYPTED_KEY_MANAGEMENT_MESSAGE:
|
||||
break;
|
||||
case UNENCRYPTED_TRUNKING_CONTROL:
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.pdu.PDUMessage;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
import decode.p25.reference.MDPConfigurationOption;
|
||||
import decode.p25.reference.PDUType;
|
||||
import decode.p25.reference.SNDCPActivationRejectReason;
|
||||
import decode.p25.reference.Vendor;
|
||||
import edac.CRC;
|
||||
import edac.CRCP25;
|
||||
|
||||
public class SNDCPActivateTDSContextAccept extends PDUConfirmedMessage
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( SNDCPActivateTDSContextAccept.class );
|
||||
|
||||
/* SN-Activate TDS Context Accept */
|
||||
public static final int[] NSAPI = { 180,181,182,183 };
|
||||
public static final int[] PDUPM = { 184,185,186,187 };
|
||||
public static final int[] READY = { 188,189,190,191 };
|
||||
public static final int[] STANDBY = { 192,193,194,195 };
|
||||
public static final int[] NAT = { 196,197,198,199 };
|
||||
public static final int[] IP_1 = { 200,201,202,203,204,205,206,207 };
|
||||
public static final int[] IP_2 = { 208,209,210,211,212,213,214,215 };
|
||||
public static final int[] IP_3 = { 216,217,218,219,220,221,222,223 };
|
||||
public static final int[] IP_4 = { 224,225,226,227,228,229,230,231 };
|
||||
public static final int[] IPHC = { 232,233,234,235,236,237,238,239 };
|
||||
public static final int[] TCPSS = { 240,241,242,243 };
|
||||
public static final int[] UDPSS = { 244,245,246,247 };
|
||||
public static final int[] MTU = { 248,249,250,251 };
|
||||
public static final int[] UDPC = { 252,253,254,255 };
|
||||
public static final int[] MDPCO = { 256,257,258,259,260,261,262,263 };
|
||||
public static final int[] DATA_ACCESS_CONTROL = { 264,265,266,267,268,
|
||||
269,270,271,272,273,274,275,276,277,278,279 };
|
||||
|
||||
public SNDCPActivateTDSContextAccept( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " LLID:" );
|
||||
sb.append( getLogicalLinkID() );
|
||||
sb.append( " ACCEPT SNDCP PACKET DATA ACTIVATE " );
|
||||
sb.append( getNetworkAddressType() );
|
||||
sb.append( " " );
|
||||
sb.append( getIPAddress() );
|
||||
sb.append( " NSAPI:" );
|
||||
sb.append( getNSAPI() );
|
||||
sb.append( " MTU:" );
|
||||
sb.append( getMaximumTransmissionUnit() );
|
||||
sb.append( " CRC[" );
|
||||
sb.append( getErrorStatus() );
|
||||
sb.append( "]" );
|
||||
|
||||
sb.append( " PACKET #" );
|
||||
sb.append( getPacketSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() && getFragmentSequenceNumber() == 0 )
|
||||
{
|
||||
sb.append( ".C" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append( "." );
|
||||
sb.append( getFragmentSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() )
|
||||
{
|
||||
sb.append( "C" );
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( " " );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Service Access Point Identifier - up to 14 NSAPI's can be
|
||||
* allocated to the mobile with each NSAPI to be used for a specific
|
||||
* protocol layer.
|
||||
*/
|
||||
public int getNSAPI()
|
||||
{
|
||||
return mMessage.getInt( NSAPI );
|
||||
}
|
||||
|
||||
public int getPDUPriorityMaximum()
|
||||
{
|
||||
return mMessage.getInt( PDUPM );
|
||||
}
|
||||
|
||||
public String getReadyTimer()
|
||||
{
|
||||
switch( mMessage.getInt( READY ) )
|
||||
{
|
||||
case 1:
|
||||
return "1 Second";
|
||||
case 2:
|
||||
return "2 Seconds";
|
||||
case 3:
|
||||
return "4 Seconds";
|
||||
case 4:
|
||||
return "6 Seconds";
|
||||
case 5:
|
||||
return "8 Seconds";
|
||||
case 6:
|
||||
return "10 Seconds";
|
||||
case 7:
|
||||
return "15 Seconds";
|
||||
case 8:
|
||||
return "20 Seconds";
|
||||
case 9:
|
||||
return "25 Seconds";
|
||||
case 10:
|
||||
return "30 Seconds";
|
||||
case 11:
|
||||
return "60 Seconds";
|
||||
case 12:
|
||||
return "120 Seconds";
|
||||
case 13:
|
||||
return "180 Seconds";
|
||||
case 14:
|
||||
return "300 Seconds";
|
||||
case 15:
|
||||
return "Always in Ready";
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
|
||||
public String getStandbyTimer()
|
||||
{
|
||||
switch( mMessage.getInt( STANDBY ) )
|
||||
{
|
||||
case 1:
|
||||
return "10 Seconds";
|
||||
case 2:
|
||||
return "30 Seconds";
|
||||
case 3:
|
||||
return "1 Minutes";
|
||||
case 4:
|
||||
return "5 Minutes";
|
||||
case 5:
|
||||
return "10 Minutes";
|
||||
case 6:
|
||||
return "30 Minutes";
|
||||
case 7:
|
||||
return "1 Hour";
|
||||
case 8:
|
||||
return "2 Hours";
|
||||
case 9:
|
||||
return "4 Hours";
|
||||
case 10:
|
||||
return "8 Hours";
|
||||
case 11:
|
||||
return "12 Hours";
|
||||
case 12:
|
||||
return "24 Hours";
|
||||
case 13:
|
||||
return "48 Hours";
|
||||
case 14:
|
||||
return "72 Hours";
|
||||
case 15:
|
||||
return "Always in Ready";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
public String getNetworkAddressType()
|
||||
{
|
||||
return mMessage.getInt( NAT ) == 0 ? "IPV4 STATIC" : "IPV4 DYNAMIC";
|
||||
}
|
||||
|
||||
public String getIPAddress()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( mMessage.getInt( IP_1 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_2 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_3 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_4 ) );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean hasIPHeaderCompression()
|
||||
{
|
||||
return mMessage.getInt( IPHC ) == 1;
|
||||
}
|
||||
|
||||
public boolean hasUserDataPayloadCompression()
|
||||
{
|
||||
return mMessage.getInt( UDPC ) == 1;
|
||||
}
|
||||
|
||||
public int getTCPStateSlots()
|
||||
{
|
||||
return mMessage.getInt( TCPSS );
|
||||
}
|
||||
|
||||
public int getUDPStateSlots()
|
||||
{
|
||||
return mMessage.getInt( UDPSS );
|
||||
}
|
||||
|
||||
public String getMaximumTransmissionUnit()
|
||||
{
|
||||
int mtu = mMessage.getInt( MTU );
|
||||
|
||||
switch( mtu )
|
||||
{
|
||||
case 1:
|
||||
return "296 BYTES";
|
||||
case 2:
|
||||
return "510 BYTES";
|
||||
case 3:
|
||||
return "1020 BYTES";
|
||||
case 4:
|
||||
return "1500 BYTES";
|
||||
default:
|
||||
return "UNK-" + mtu;
|
||||
}
|
||||
}
|
||||
|
||||
public MDPConfigurationOption getMDPConfigurationOption()
|
||||
{
|
||||
return MDPConfigurationOption.fromValue( mMessage.getInt( MDPCO ) );
|
||||
}
|
||||
|
||||
public String getDataAccessControl()
|
||||
{
|
||||
return mMessage.getHex( DATA_ACCESS_CONTROL, 4 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import decode.p25.reference.SNDCPActivationRejectReason;
|
||||
|
||||
public class SNDCPActivateTDSContextReject extends PDUConfirmedMessage
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( SNDCPActivateTDSContextReject.class );
|
||||
|
||||
public static final int[] NSAPI = { 180,181,182,183 };
|
||||
public static final int[] REJECT_CODE = { 184,185,186,187,188,189,190,191 };
|
||||
|
||||
public SNDCPActivateTDSContextReject( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " LLID:" );
|
||||
sb.append( getLogicalLinkID() );
|
||||
sb.append( " REJECT SNDCP PACKET DATA ACTIVATE - REASON:" );
|
||||
sb.append( getReason().getLabel() );
|
||||
sb.append( " CRC[" );
|
||||
sb.append( getErrorStatus() );
|
||||
sb.append( "] " );
|
||||
sb.append( mMessage.toString() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Service Access Point Identifier - up to 14 NSAPI's can be
|
||||
* allocated to the mobile with each NSAPI to be used for a specific
|
||||
* protocol layer.
|
||||
*/
|
||||
public int getNSAPI()
|
||||
{
|
||||
return mMessage.getInt( NSAPI );
|
||||
}
|
||||
|
||||
public SNDCPActivationRejectReason getReason()
|
||||
{
|
||||
return SNDCPActivationRejectReason.fromValue( mMessage.getInt( REJECT_CODE ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import decode.p25.reference.MDPConfigurationOption;
|
||||
|
||||
public class SNDCPActivateTDSContextRequest extends PDUConfirmedMessage
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( SNDCPActivateTDSContextRequest.class );
|
||||
|
||||
public static final int[] SNDCP_VERSION = { 180,181,182,183 };
|
||||
public static final int[] NSAPI = { 184,185,186,187 };
|
||||
public static final int[] NAT = { 188,189,190,191 };
|
||||
public static final int[] IP_1 = { 192,193,194,195,196,197,198,199 };
|
||||
public static final int[] IP_2 = { 200,201,202,203,204,205,206,207 };
|
||||
public static final int[] IP_3 = { 208,209,210,211,212,213,214,215 };
|
||||
public static final int[] IP_4 = { 216,217,218,219,220,221,222,223 };
|
||||
public static final int[] DSUT = { 224,225,226,227 };
|
||||
public static final int[] UDPC = { 228,229,230,231 };
|
||||
public static final int[] IPHC = { 232,233,234,235,236,237,238,239 };
|
||||
public static final int[] TCPSS = { 240,241,242,243 };
|
||||
public static final int[] UDPSS = { 244,245,246,247 };
|
||||
public static final int[] MDPCO = { 248,249,250,251,252,253,254,255 };
|
||||
|
||||
public SNDCPActivateTDSContextRequest( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " LLID:" );
|
||||
sb.append( getLogicalLinkID() );
|
||||
sb.append( " REQUEST SNDCP PACKET DATA ACTIVATE " );
|
||||
sb.append( getNetworkAddressType() );
|
||||
sb.append( " " );
|
||||
sb.append( getIPAddress() );
|
||||
sb.append( " NSAPI:" );
|
||||
sb.append( getNSAPI() );
|
||||
sb.append( " CRC[" );
|
||||
sb.append( getErrorStatus() );
|
||||
sb.append( "]" );
|
||||
|
||||
sb.append( " PACKET #" );
|
||||
sb.append( getPacketSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() && getFragmentSequenceNumber() == 0 )
|
||||
{
|
||||
sb.append( ".C" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append( "." );
|
||||
sb.append( getFragmentSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() )
|
||||
{
|
||||
sb.append( "C" );
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( " " );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* SNDCP Version: 1 = P25 SNDCP Version 1
|
||||
*/
|
||||
public int getSNDCPVersion()
|
||||
{
|
||||
return mMessage.getInt( SNDCP_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Service Access Point Identifier - up to 14 NSAPI's can be
|
||||
* allocated to the mobile with each NSAPI to be used for a specific
|
||||
* protocol layer.
|
||||
*/
|
||||
public int getNSAPI()
|
||||
{
|
||||
return mMessage.getInt( NSAPI );
|
||||
}
|
||||
|
||||
public String getNetworkAddressType()
|
||||
{
|
||||
return mMessage.getInt( NAT ) == 0 ? "IPV4 STATIC" : "IPV4 DYNAMIC";
|
||||
}
|
||||
|
||||
public String getIPAddress()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( mMessage.getInt( IP_1 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_2 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_3 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( IP_4 ) );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getDataSubscriberUnitType()
|
||||
{
|
||||
switch( mMessage.getInt( DSUT ) )
|
||||
{
|
||||
case 0:
|
||||
return "DATA ONLY MRC";
|
||||
case 1:
|
||||
return "DATA AND VOICE MRC";
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
public boolean hasIPHeaderCompression()
|
||||
{
|
||||
return mMessage.getInt( IPHC ) == 1;
|
||||
}
|
||||
|
||||
public boolean hasUserDataPayloadCompression()
|
||||
{
|
||||
return mMessage.getInt( UDPC ) == 1;
|
||||
}
|
||||
|
||||
public int getTCPStateSlots()
|
||||
{
|
||||
return mMessage.getInt( TCPSS );
|
||||
}
|
||||
|
||||
public int getUDPStateSlots()
|
||||
{
|
||||
return mMessage.getInt( UDPSS );
|
||||
}
|
||||
|
||||
public MDPConfigurationOption getMDPConfigurationOption()
|
||||
{
|
||||
return MDPConfigurationOption.fromValue( mMessage.getInt( MDPCO ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import decode.p25.reference.PDUType;
|
||||
import decode.p25.reference.SNDCPActivationRejectReason;
|
||||
|
||||
public class SNDCPDeactivateTDSContext extends PDUConfirmedMessage
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( SNDCPDeactivateTDSContext.class );
|
||||
|
||||
public static final int[] NSAPI = { 180,181,182,183 };
|
||||
public static final int[] DEACTIVATION_TYPE = { 184,185,186,187,188,189,
|
||||
190,191 };
|
||||
|
||||
public SNDCPDeactivateTDSContext( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " LLID:" );
|
||||
sb.append( getLogicalLinkID() );
|
||||
sb.append( " REQUEST SNDCP PACKET DATA DEACTIVATE " );
|
||||
sb.append( getDeactivationType() );
|
||||
sb.append( " CRC[" );
|
||||
sb.append( getErrorStatus() );
|
||||
sb.append( "] " );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Service Access Point Identifier - up to 14 NSAPI's can be
|
||||
* allocated to the mobile with each NSAPI to be used for a specific
|
||||
* protocol layer.
|
||||
*/
|
||||
public int getNSAPI()
|
||||
{
|
||||
return mMessage.getInt( NSAPI );
|
||||
}
|
||||
|
||||
public String getDeactivationType()
|
||||
{
|
||||
if( getPDUType() == PDUType.SN_DEACTIVATE_TDS_CONTEXT_REQUEST )
|
||||
{
|
||||
return mMessage.getInt( DEACTIVATION_TYPE ) == 0 ?
|
||||
"ALL NSAPIS" : "THIS NSAPI";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
356
src/decode/p25/message/pdu/confirmed/SNDCPUserData.java
Normal file
356
src/decode/p25/message/pdu/confirmed/SNDCPUserData.java
Normal file
@@ -0,0 +1,356 @@
|
||||
package decode.p25.message.pdu.confirmed;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import decode.p25.reference.IPHeaderCompression;
|
||||
import decode.p25.reference.IPProtocol;
|
||||
|
||||
public class SNDCPUserData extends PDUConfirmedMessage
|
||||
{
|
||||
public final static Logger mLog =
|
||||
LoggerFactory.getLogger( SNDCPUserData.class );
|
||||
|
||||
public static final int DATA_BLOCK_START = 176;
|
||||
|
||||
public static final int[] NSAPI = { 180,181,182,183 };
|
||||
public static final int[] PCOMP = { 184,185,186,187 };
|
||||
public static final int[] DCOMP = { 188,189,190,191 };
|
||||
|
||||
/* IP Packet Header */
|
||||
public static final int[] IP_VERSION = { 192,193,194,195 };
|
||||
public static final int[] IHL = { 196,197,198,199 };
|
||||
public static final int[] DSCP = { 200,201,202,203,204,205 };
|
||||
public static final int[] ECN = { 206,207 };
|
||||
public static final int[] TOTAL_LENGTH = { 208,209,210,211,212,213,214,215,
|
||||
216,217,218,219,220,221,222,223 };
|
||||
public static final int[] IDENTIFICATION = { 224,225,226,227,228,229,230,231,
|
||||
232,233,234,235,236,237,238,239 };
|
||||
public static final int[] FLAGS = { 240,241,242 };
|
||||
public static final int[] FRAGMENT_OFFSET = { 243,244,245,246,247,248,249,
|
||||
250,251,252,253,254,255 };
|
||||
public static final int[] TTL = { 256,257,258,259,260,261,262,263 };
|
||||
public static final int[] PROTOCOL = { 264,265,266,267,268,269,270,271 };
|
||||
public static final int[] HEADER_CHECKSUM = { 272,273,274,275,276,277,278,
|
||||
279,280,281,282,283,284,285,286,287 };
|
||||
public static final int[] SOURCE_IP_1 = { 288,289,290,291,292,293,294,295 };
|
||||
public static final int[] SOURCE_IP_2 = { 296,297,298,299,300,301,302,303 };
|
||||
public static final int[] BLOCK_SERIAL_2 = { 304,305,306,307,308,309,310 };
|
||||
public static final int[] BLOCK_CRC9_2 = { 311,312,313,314,315,316,317,318,
|
||||
319 };
|
||||
public static final int[] SOURCE_IP_3 = { 320,321,322,323,324,325,326,327 };
|
||||
public static final int[] SOURCE_IP_4 = { 328,329,330,331,332,333,334,335 };
|
||||
public static final int[] DESTINATION_IP_1 = { 336,337,338,339,340,341,342,343 };
|
||||
public static final int[] DESTINATION_IP_2 = { 344,345,346,347,348,349,350,351 };
|
||||
public static final int[] DESTINATION_IP_3 = { 352,353,354,355,356,357,358,359 };
|
||||
public static final int[] DESTINATION_IP_4 = { 360,361,362,363,364,365,366,367 };
|
||||
|
||||
public static final int IP_DATA_START = 368;
|
||||
|
||||
/* User Datagram Protocol */
|
||||
public static final int[] UDP_SOURCE_PORT = { 368,369,370,371,372,373,374,
|
||||
375 };
|
||||
public static final int[] UDP_DESTINATION_PORT = { 376,377,378,379,380,381,
|
||||
382,383 };
|
||||
public static final int[] UDP_LENGTH = { 384,385,386,387,388,389,390,391,
|
||||
392,393,394,395,396,397,398,399 };
|
||||
public static final int[] UDP_CHECKSUM = { 400,401,402,403,404,405,406,407,
|
||||
408,409,410,411,412,413,414,415 };
|
||||
public static final int UDP_DATA_START = 416;
|
||||
|
||||
public SNDCPUserData( PDUConfirmedMessage message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( "NAC:" );
|
||||
sb.append( getNAC() );
|
||||
sb.append( " LLID:" );
|
||||
sb.append( getLogicalLinkID() );
|
||||
sb.append( " SNDCP NSAPI:" );
|
||||
sb.append( getNSAPI() );
|
||||
sb.append( " " );
|
||||
IPProtocol protocol = getIPProtocol();
|
||||
|
||||
sb.append( protocol.getLabel() );
|
||||
sb.append( "/IP" );
|
||||
|
||||
sb.append( " FM:" );
|
||||
sb.append( getSourceIPAddress() );
|
||||
|
||||
if( protocol == IPProtocol.UDP )
|
||||
{
|
||||
sb.append( ":" );
|
||||
sb.append( getUDPSourcePort() );
|
||||
}
|
||||
|
||||
sb.append( " TO:" );
|
||||
sb.append( getDestinationIPAddress() );
|
||||
|
||||
if( protocol == IPProtocol.UDP )
|
||||
{
|
||||
sb.append( ":" );
|
||||
sb.append( getUDPDestinationPort() );
|
||||
}
|
||||
|
||||
sb.append( " DATA:" );
|
||||
sb.append( getPayload() );
|
||||
|
||||
sb.append( " CRC[" );
|
||||
sb.append( getErrorStatus() );
|
||||
sb.append( "]" );
|
||||
|
||||
sb.append( " PACKET #" );
|
||||
sb.append( getPacketSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() && getFragmentSequenceNumber() == 0 )
|
||||
{
|
||||
sb.append( ".C" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append( "." );
|
||||
sb.append( getFragmentSequenceNumber() );
|
||||
|
||||
if( isFinalFragment() )
|
||||
{
|
||||
sb.append( "C" );
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( " " );
|
||||
|
||||
sb.append( mMessage.toString() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Service Access Point Identifier - up to 14 NSAPI's can be
|
||||
* allocated to the mobile with each NSAPI to be used for a specific
|
||||
* protocol layer.
|
||||
*/
|
||||
public int getNSAPI()
|
||||
{
|
||||
return mMessage.getInt( NSAPI );
|
||||
}
|
||||
|
||||
public IPHeaderCompression getIPHeaderCompressionState()
|
||||
{
|
||||
return IPHeaderCompression.fromValue( mMessage.getInt( PCOMP ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* No enum values were defined for this
|
||||
*/
|
||||
public boolean hasUserDataCompression()
|
||||
{
|
||||
return mMessage.getInt( DCOMP ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP Version - should always be 4 (IPV4)
|
||||
*/
|
||||
public int getIPVersion()
|
||||
{
|
||||
return mMessage.getInt( IP_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet header length in 32-bit words
|
||||
*/
|
||||
public int getInternetHeaderLength()
|
||||
{
|
||||
return mMessage.getInt( IHL );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet DSCP
|
||||
*/
|
||||
public int getDifferentiatedServicesCodePoint()
|
||||
{
|
||||
return mMessage.getInt( DSCP );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet ECN
|
||||
*/
|
||||
public int getExplicitCongestionNotification()
|
||||
{
|
||||
return mMessage.getInt( ECN );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet size in bytes, including header and data
|
||||
*/
|
||||
public int getTotalLength()
|
||||
{
|
||||
return mMessage.getInt( TOTAL_LENGTH );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet identification
|
||||
*/
|
||||
public int getIdentification()
|
||||
{
|
||||
return mMessage.getInt( IDENTIFICATION );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet flags. 0-Reserved, 1-Don't Fragment, 2-More Fragments
|
||||
*/
|
||||
public int getFlags()
|
||||
{
|
||||
return mMessage.getInt( FLAGS );
|
||||
}
|
||||
|
||||
public boolean isFragment()
|
||||
{
|
||||
return getFlags() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet - identifies the offset value in 8-byte blocks (64-bit blocks)
|
||||
* for this packet fragment from the beginning.
|
||||
*/
|
||||
public int getFragmentOffset()
|
||||
{
|
||||
return mMessage.getInt( FRAGMENT_OFFSET );
|
||||
}
|
||||
|
||||
/**
|
||||
* IP packet time (hops) to live
|
||||
*/
|
||||
public int getTimeToLive()
|
||||
{
|
||||
return mMessage.getInt( TTL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the IP protocol carried by the IP packet
|
||||
*/
|
||||
public IPProtocol getIPProtocol()
|
||||
{
|
||||
return IPProtocol.fromValue( mMessage.getInt( PROTOCOL ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Source IPV4 address
|
||||
*/
|
||||
public String getSourceIPAddress()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( mMessage.getInt( SOURCE_IP_1 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( SOURCE_IP_2 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( SOURCE_IP_3 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( SOURCE_IP_4 ) );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destination IPV4 address
|
||||
*/
|
||||
public String getDestinationIPAddress()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( mMessage.getInt( DESTINATION_IP_1 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( DESTINATION_IP_2 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( DESTINATION_IP_3 ) );
|
||||
sb.append( "." );
|
||||
sb.append( mMessage.getInt( DESTINATION_IP_4 ) );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP source port
|
||||
*/
|
||||
public int getUDPSourcePort()
|
||||
{
|
||||
return mMessage.getInt( UDP_SOURCE_PORT );
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP destination port
|
||||
*/
|
||||
public int getUDPDestinationPort()
|
||||
{
|
||||
return mMessage.getInt( UDP_DESTINATION_PORT );
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP data payload size in bytes
|
||||
*/
|
||||
public int getUDPDataLength()
|
||||
{
|
||||
return mMessage.getInt( UDP_LENGTH );
|
||||
}
|
||||
/**
|
||||
* Hex string representation of the packet data, including packet header
|
||||
* data if present.
|
||||
*/
|
||||
public String getPayload()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
/* Adjust for PDU header (2 bytes) plus IP Packet header (20 bytes) */
|
||||
int start = 22;
|
||||
|
||||
if( getIPProtocol() == IPProtocol.UDP )
|
||||
{
|
||||
/* Adjust for UDP header (8 bytes) */
|
||||
start = 30;
|
||||
}
|
||||
|
||||
int spacingCounter = 0;
|
||||
|
||||
/* Append octets inserting a space between each 32-bit value */
|
||||
int octets = getOctetCount() + getDataHeaderOffset();
|
||||
|
||||
for( int x = start; x < octets; x++ )
|
||||
{
|
||||
sb.append( getPacketOctet( x ) );
|
||||
|
||||
spacingCounter++;
|
||||
|
||||
if( spacingCounter >= 4 )
|
||||
{
|
||||
sb.append( " " );
|
||||
spacingCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the octet identified by the 0-indexed 'octet' argument location.
|
||||
* If there is a Data Header Offset, the 0 index points to the first octet
|
||||
* of the data header. Otherwise, the 0 index points to the first octet
|
||||
* of the packet. You must account for the data header offset when
|
||||
* specifying the octet.
|
||||
*/
|
||||
public String getPacketOctet( int octet )
|
||||
{
|
||||
int block = (int)( octet / 16 );
|
||||
int offset = octet % 16;
|
||||
|
||||
int start = DATA_BLOCK_START + ( block * 144 ) + ( offset * 8 );
|
||||
|
||||
return mMessage.getHex( start, start + 7, 2 );
|
||||
}
|
||||
|
||||
}
|
||||
38
src/decode/p25/reference/IPHeaderCompression.java
Normal file
38
src/decode/p25/reference/IPHeaderCompression.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package decode.p25.reference;
|
||||
|
||||
public enum IPHeaderCompression
|
||||
{
|
||||
NONE( 0, "NONE" ),
|
||||
RFC1144_COMPRESSED( 1, "RFC-1144 COMPRESSED" ),
|
||||
RFC1144_UNCOMPRESSED( 2, "RFC-1144 UNCOMPRESSED" ),
|
||||
UNKNOWN( -1, "UNKNOWN" );
|
||||
|
||||
private int mValue;
|
||||
private String mLabel;
|
||||
|
||||
private IPHeaderCompression( int value, String label )
|
||||
{
|
||||
mValue = value;
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public static IPHeaderCompression fromValue( int value )
|
||||
{
|
||||
if( 0 <= value && value <= 2 )
|
||||
{
|
||||
return values()[ value ];
|
||||
}
|
||||
|
||||
return IPHeaderCompression.UNKNOWN;
|
||||
}
|
||||
}
|
||||
178
src/decode/p25/reference/IPProtocol.java
Normal file
178
src/decode/p25/reference/IPProtocol.java
Normal file
@@ -0,0 +1,178 @@
|
||||
package decode.p25.reference;
|
||||
|
||||
public enum IPProtocol
|
||||
{
|
||||
HOPOPT( 0, "IPV6 HOP-BY-HOP" ),
|
||||
ICMP( 1, "ICMP" ),
|
||||
IGMP( 2, "IGMP" ),
|
||||
GGP( 3, "GGP" ),
|
||||
IPinIP( 4, "IPinIP" ),
|
||||
ST( 5, "ST" ),
|
||||
TCP( 6, "TCP" ),
|
||||
CBT( 7, "CBT" ),
|
||||
EGP( 8, "EGP" ),
|
||||
IGP( 9, "IGP" ),
|
||||
BBN( 10, "BBN" ),
|
||||
NVP( 11, "NVP" ),
|
||||
PUP( 12, "PUP" ),
|
||||
ARGUS( 13, "ARGUS" ),
|
||||
EMCON( 14, "EMCON" ),
|
||||
XNET( 15, "XNET" ),
|
||||
CHAOS( 16, "CHAOS" ),
|
||||
UDP( 17, "UDP" ),
|
||||
MUX( 18, "MUX" ),
|
||||
DCN( 19, "DCN" ),
|
||||
HMP( 20, "HMP" ),
|
||||
PRM( 21, "PRM" ),
|
||||
XNS_IDP( 22, "XNS-IDP" ),
|
||||
TRUNK_1( 23, "TRUNK-1" ),
|
||||
TRUNK_2( 24, "TRUNK-2" ),
|
||||
LEAF_1( 25, "LEAF-1" ),
|
||||
LEAF_2( 26, "LEAF-2" ),
|
||||
RDP( 27, "RDP" ),
|
||||
IRTP( 28, "IRTP" ),
|
||||
ISO_TP4( 29, "ISO-TP4" ),
|
||||
NETBLT( 30, "NETBLT" ),
|
||||
MFE_NSP( 31, "MFE-NSP" ),
|
||||
MERIT_INP( 32, "MERIT-INP" ),
|
||||
DCCP( 33, "DCCP" ),
|
||||
_3PC( 34, "3PC" ),
|
||||
IDPR( 35, "IDPR" ),
|
||||
XTP( 36, "XTP" ),
|
||||
DDP( 37, "DDP" ),
|
||||
IDPR_CMTP( 38, "IDPR-CMTP" ),
|
||||
TPPP( 39, "TP++" ),
|
||||
IL( 40, "IL" ),
|
||||
IPV6( 41, "IPV6" ),
|
||||
SDRP( 42, "SDRP" ),
|
||||
IPV6_ROUTE( 43, "IPV6-ROUTE" ),
|
||||
IPV6_FRAG( 44, "IPV6-FRAG" ),
|
||||
IDRP( 45, "IDRP" ),
|
||||
RSVP( 46, "RSVP" ),
|
||||
GRE( 47, "GRE" ),
|
||||
MHRP( 48, "MHRP" ),
|
||||
BNA( 49, "BNA" ),
|
||||
ESP( 50, "ESP" ),
|
||||
AH( 51, "AH" ),
|
||||
INLSP( 52, "I-NLSP" ),
|
||||
SWIPE( 53, "SWIPE" ),
|
||||
NARP( 54, "NARP" ),
|
||||
MOBILE( 55, "MOBILE" ),
|
||||
TLSP( 56, "TLSP" ),
|
||||
SKIP( 57, "SKIP" ),
|
||||
IPV6_ICMP( 58, "IPV6-ICMP" ),
|
||||
IPV6_NONXT( 59, "IPV6-NoNXT" ),
|
||||
IPV6_OPTS( 60, "IPV6-OPTS" ),
|
||||
ANY_HOST( 61, "ANY HOST" ),
|
||||
CFTP( 62, "CFTP" ),
|
||||
ANY_NETWORK( 63, "ANY NETWORK" ),
|
||||
SAT_EXPAK( 64, "SAT_EXPAK" ),
|
||||
KRYPTOLAN( 65, "KRYPTOLAN" ),
|
||||
RVD( 66, "RVD" ),
|
||||
IPPC( 67, "IPPC" ),
|
||||
ANY_DIST( 68, "ANY DISTRIBUTED" ),
|
||||
SAT_MON( 69, "SAT-MON" ),
|
||||
VISA( 70, "VISA" ),
|
||||
IPCU( 71, "IPCU" ),
|
||||
CPNX( 72, "CPNX" ),
|
||||
CPHB( 73, "CPHB" ),
|
||||
WSN( 74, "WSN" ),
|
||||
PVP( 75, "PVP" ),
|
||||
BR_SAT_MON( 76, "BR-SAT-MON" ),
|
||||
SUN_ND( 77, "SUN-ND" ),
|
||||
WB_MON( 78, "WB-MON" ),
|
||||
WB_EXPAK( 79, "WB-EXPAK" ),
|
||||
ISO_IP( 80, "ISO-IP" ),
|
||||
VMTP( 81, "VMTP" ),
|
||||
SECURE_VMTP( 82, "SECURE-VMTP" ),
|
||||
VINES( 83, "VINES" ),
|
||||
TTP( 84, "TTP" ),
|
||||
NSFNET_IGP( 85, "NSFNET-IGP" ),
|
||||
DGP( 86, "DGP" ),
|
||||
TCF( 87, "TCF" ),
|
||||
EIGRP( 88, "EIGRP" ),
|
||||
OSPF( 89, "OSPF" ),
|
||||
SPRITE_RPC( 90, "SPRITE-RPC" ),
|
||||
LARP( 91, "LARP" ),
|
||||
MTP( 92, "MTP" ),
|
||||
AX25( 93, "AX-25" ),
|
||||
IPIP( 94, "IPIP" ),
|
||||
MICP( 95, "MICP" ),
|
||||
SCC_SP( 96, "SCC-SP" ),
|
||||
ETHERIP( 97, "ETHER-IP" ),
|
||||
ENCAP( 98, "ENCAP" ),
|
||||
ANY_PRIVATE( 99, "ANY PRIVATE" ),
|
||||
GMTP( 100, "GMTP" ),
|
||||
IFMP( 101, "IFMP" ),
|
||||
PNNI( 102, "PNNI" ),
|
||||
PIM( 103, "PIM" ),
|
||||
ARIS( 104, "ARIS" ),
|
||||
SCPS( 105, "SCPS" ),
|
||||
QNX( 106, "QNX" ),
|
||||
A_N( 107, "A-N" ),
|
||||
IPCOMP( 108, "IPCOMP" ),
|
||||
SNP( 109, "SNP" ),
|
||||
COMPAQ_PEER( 110, "COMPAQ-PEER" ),
|
||||
IPXinIP( 111, "IPX-in-IP" ),
|
||||
VRRP( 112, "VRRP" ),
|
||||
PGM( 113, "PGM" ),
|
||||
ANY_0_HOP( 114, "ANY 0-HOP" ),
|
||||
L2TP( 115, "L2TP" ),
|
||||
DDX( 116, "DDX" ),
|
||||
IATP( 117, "IATP" ),
|
||||
STP( 118, "STP" ),
|
||||
SRP( 119, "SRP" ),
|
||||
UTI( 120, "UTI" ),
|
||||
SMP( 121, "SMP" ),
|
||||
SM( 122, "SM" ),
|
||||
PTP( 123, "PTP" ),
|
||||
ISIS( 124, "IS-IS OVER IPV4" ),
|
||||
FIRE( 125, "FIRE" ),
|
||||
CRTP( 126, "CRTP" ),
|
||||
CRUDP( 127, "CRUDP" ),
|
||||
SSCOPMCE( 128, "SSCOPMCE" ),
|
||||
IPLT( 129, "IPLT" ),
|
||||
SPS( 130, "SPS" ),
|
||||
PIPE( 131, "PIPE" ),
|
||||
SCTP( 132, "SCTP" ),
|
||||
FC( 133, "FC" ),
|
||||
RSVP_E2E( 134, "RSVP E2E" ),
|
||||
MOBILITY( 135, "MOBILITY HDR" ),
|
||||
UDPLITE( 136, "UDP LITE" ),
|
||||
MPLSinIP( 137, "MPLS-IN-IP" ),
|
||||
MANET( 138, "MANET" ),
|
||||
HIP( 139, "HIP" ),
|
||||
SHIM6( 140, "SHIM6" ),
|
||||
WESP( 141, "WESP" ),
|
||||
ROHC( 142, "ROHC" ),
|
||||
UNKNOWN( -1, "UNKNOWN" );
|
||||
|
||||
private int mValue;
|
||||
private String mLabel;
|
||||
|
||||
private IPProtocol( int value, String label )
|
||||
{
|
||||
mValue = value;
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public static IPProtocol fromValue( int value )
|
||||
{
|
||||
if( 0 <= value && value <= 142 )
|
||||
{
|
||||
return values()[ value ];
|
||||
}
|
||||
|
||||
return IPProtocol.UNKNOWN;
|
||||
}
|
||||
}
|
||||
38
src/decode/p25/reference/MDPConfigurationOption.java
Normal file
38
src/decode/p25/reference/MDPConfigurationOption.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package decode.p25.reference;
|
||||
|
||||
public enum MDPConfigurationOption
|
||||
{
|
||||
INTERNAL( "INTERNAL INTERFACE", 0 ),
|
||||
MDP_SLIP( "MDP SLIP", 1 ),
|
||||
MDP_PPP( "MDP PPP", 2 ),
|
||||
UNKNOWN( "UNKNOWN", -1 );
|
||||
|
||||
private String mLabel;
|
||||
private int mValue;
|
||||
|
||||
private MDPConfigurationOption( String label, int value )
|
||||
{
|
||||
mLabel = label;
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public static MDPConfigurationOption fromValue( int value )
|
||||
{
|
||||
if( 0 <= value && value <= 2 )
|
||||
{
|
||||
return values()[ value ];
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
50
src/decode/p25/reference/PDUType.java
Normal file
50
src/decode/p25/reference/PDUType.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package decode.p25.reference;
|
||||
|
||||
public enum PDUType
|
||||
{
|
||||
/* Outbound */
|
||||
SN_ACTIVATE_TDS_CONTEXT_ACCEPT( "SN-ACTIVATE TDS CONTEXT ACCEPT", 0 ),
|
||||
SN_DEACTIVATE_TDS_CONTEXT_ACCEPT( "SN-DEACTIVATE TDS CONTEXT ACCEPT", 1 ),
|
||||
SN_DEACTIVATE_TDS_CONTEXT_REQUEST( "SN-DEACTIVATE TDS CONTEXT REQUEST", 2 ),
|
||||
SN_ACTIVATE_TDS_CONTEXT_REJECT( "SN-ACTIVATE TDS CONTEXT REJECT", 3 ),
|
||||
SN_RF_UNCONFIRMED_DATA( "SN-RF UNCONFIRMED DATA", 4 ),
|
||||
SN_RF_CONFIRMED_DATA( "SN-RF CONFIRMED DATA", 5 ),
|
||||
|
||||
/* Inbound */
|
||||
SN_ACTIVATE_TDS_CONTEXT_REQUEST( "SN-ACTIVATE TDS CONTEXT REQUEST", 0 ),
|
||||
|
||||
UNKNOWN( "UNKNOWN", -1 );
|
||||
|
||||
private String mLabel;
|
||||
private int mValue;
|
||||
|
||||
private PDUType( String label, int value )
|
||||
{
|
||||
mLabel = label;
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public static PDUType fromValue( int value, boolean outbound )
|
||||
{
|
||||
if( outbound && 0 <= value && value <= 5 )
|
||||
{
|
||||
return values()[ value ];
|
||||
}
|
||||
else if( value == 0 && !outbound )
|
||||
{
|
||||
return SN_ACTIVATE_TDS_CONTEXT_REQUEST;
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
53
src/decode/p25/reference/SNDCPActivationRejectReason.java
Normal file
53
src/decode/p25/reference/SNDCPActivationRejectReason.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package decode.p25.reference;
|
||||
|
||||
public enum SNDCPActivationRejectReason
|
||||
{
|
||||
R0( 0, "ANY REASON" ),
|
||||
R1( 1, "MRC NOT PROVISIONED FOR TDS" ),
|
||||
R2( 2, "MRC DSUT NOT SUPPORTED" ),
|
||||
R3( 3, "MAX TDS CONTEXTS EXCEEDED" ),
|
||||
R4( 4, "SNDCP VERSION NOT SUPPORTED" ),
|
||||
R5( 5, "TDS NOT SUPPORTED BY FNE" ),
|
||||
R6( 6, "TDS NOT SUPPORTED BY THIS SYSTEM" ),
|
||||
R7( 7, "IPV4 STATIC ADDRESS NOT CORRECT" ),
|
||||
R8( 8, "IPV4 STATIC ADDRESS NOT ALLOWED" ),
|
||||
R9( 9, "IPV4 STATIC ADDRESS IN USE" ),
|
||||
R10( 10, "IPV4 NOT SUPPORTED" ),
|
||||
R11( 11, "IPV4 DYNAMIC ADDRESS POOL EMPTY" ),
|
||||
R12( 12, "IPV4 DYNAMIC ADDRESS NOT SUPPORTED" ),
|
||||
UNKNOWN( -1, "UNKNOWN" );
|
||||
|
||||
private int mValue;
|
||||
public String mLabel;
|
||||
|
||||
private SNDCPActivationRejectReason( int value, String label )
|
||||
{
|
||||
mValue = value;
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getLabel();
|
||||
}
|
||||
|
||||
public static SNDCPActivationRejectReason fromValue( int value )
|
||||
{
|
||||
if( 0 <= value && value <= 12 )
|
||||
{
|
||||
return values()[ value ];
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class C4FMSymbolFilter implements FrequencyChangeBroadcaster,
|
||||
|
||||
private RealSampleListener mListener;
|
||||
|
||||
public static final long MAX_FREQUENCY_CORRECTION = 7000;
|
||||
public static final long MAX_FREQUENCY_CORRECTION = 3000;
|
||||
private FrequencyChangeListener mFrequencyChangeListener;
|
||||
private long mFrequencyCorrection;
|
||||
|
||||
|
||||
@@ -20,9 +20,10 @@ import decode.p25.message.hdu.HDUMessage;
|
||||
import decode.p25.message.ldu.LDU1Message;
|
||||
import decode.p25.message.ldu.LDU2Message;
|
||||
import decode.p25.message.ldu.lc.LDULCMessageFactory;
|
||||
import decode.p25.message.pdu.PDUConfirmedMessage;
|
||||
import decode.p25.message.pdu.PDUMessage;
|
||||
import decode.p25.message.pdu.PDUMessageFactory;
|
||||
import decode.p25.message.pdu.confirmed.PDUConfirmedMessage;
|
||||
import decode.p25.message.pdu.confirmed.PDUConfirmedMessageFactory;
|
||||
import decode.p25.message.tdu.TDUMessage;
|
||||
import decode.p25.message.tdu.lc.TDULCMessageFactory;
|
||||
import decode.p25.message.tdu.lc.TDULinkControlMessage;
|
||||
@@ -415,8 +416,12 @@ public class P25MessageFramer implements Listener<Dibit>
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch( new PDUConfirmedMessage( mMessage.copy(),
|
||||
mDUID, mAliasList ) );
|
||||
PDUConfirmedMessage pducm =
|
||||
new PDUConfirmedMessage( mMessage.copy(),
|
||||
mAliasList );
|
||||
|
||||
/* Translate into correct subclass */
|
||||
dispatch( PDUConfirmedMessageFactory.getMessage( pducm ) );
|
||||
|
||||
mComplete = true;
|
||||
}
|
||||
@@ -424,8 +429,12 @@ public class P25MessageFramer implements Listener<Dibit>
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch( new PDUConfirmedMessage( mMessage.copy(),
|
||||
mDUID, mAliasList ) );
|
||||
PDUConfirmedMessage pducm =
|
||||
new PDUConfirmedMessage( mMessage.copy(),
|
||||
mAliasList );
|
||||
|
||||
/* Translate into correct subclass */
|
||||
dispatch( PDUConfirmedMessageFactory.getMessage( pducm ) );
|
||||
|
||||
mComplete = true;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,6 @@ public class DirectGainControl implements GainController, RealSampleListener
|
||||
{
|
||||
mGain = mMaximum;
|
||||
}
|
||||
|
||||
mLog.debug( "Gain Increased: " + mGain );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,8 +82,6 @@ public class DirectGainControl implements GainController, RealSampleListener
|
||||
{
|
||||
mGain = mMinimum;
|
||||
}
|
||||
|
||||
mLog.debug( "Gain Decreased: " + mGain );
|
||||
}
|
||||
|
||||
public void setListener( RealSampleListener listener )
|
||||
|
||||
@@ -55,7 +55,7 @@ public class FilteringNBFMDemodulator implements Listener<ComplexSample>
|
||||
*/
|
||||
public FilteringNBFMDemodulator()
|
||||
{
|
||||
this( FilterFactory.getLowPass( 48000, 4000, 6000, 48, WindowType.HAMMING, true ),
|
||||
this( FilterFactory.getLowPass( 48000, 5000, 7000, 48, WindowType.HAMMING, true ),
|
||||
1.0002,
|
||||
FilterFactory.getLowPass( 48000, 3000, 6000, 48, WindowType.HAMMING, true ),
|
||||
2 );
|
||||
|
||||
Reference in New Issue
Block a user