mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 09:37:36 -05:00
P25 Work in progress. Adds CRC checking to NID/DUID. Adds limiter to trellis decoder to prevent it from decoding an excessive error message. Updates channel state with initial handling/generation of call events.
This commit is contained in:
@@ -24,16 +24,16 @@ import decode.DecoderType;
|
||||
|
||||
public class P25CallEvent extends CallEvent
|
||||
{
|
||||
private int mChannel;
|
||||
private String mChannel;
|
||||
private long mFrequency;
|
||||
|
||||
public P25CallEvent( CallEventType callEventType,
|
||||
AliasList aliasList,
|
||||
String fromID,
|
||||
String toID,
|
||||
int channel,
|
||||
long frequency,
|
||||
String details )
|
||||
AliasList aliasList,
|
||||
String fromID,
|
||||
String toID,
|
||||
String channel,
|
||||
long frequency,
|
||||
String details )
|
||||
{
|
||||
super( DecoderType.MPT1327, callEventType,
|
||||
aliasList, fromID, toID, details );
|
||||
@@ -42,11 +42,11 @@ public class P25CallEvent extends CallEvent
|
||||
mFrequency = frequency;
|
||||
}
|
||||
|
||||
private Alias getAlias( String mpt1327Talkgroup )
|
||||
private Alias getAlias( String talkgroup )
|
||||
{
|
||||
if( hasAliasList() )
|
||||
{
|
||||
return getAliasList().getMPT1327Alias( mpt1327Talkgroup );
|
||||
return getAliasList().getTalkgroupAlias( talkgroup );
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -65,7 +65,7 @@ public class P25CallEvent extends CallEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannel()
|
||||
public String getChannel()
|
||||
{
|
||||
return mChannel;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class P25CallEvent extends CallEvent
|
||||
private String mFromID;
|
||||
private String mToID;
|
||||
private String mDetails;
|
||||
private int mChannel;
|
||||
private String mChannel;
|
||||
private long mFrequency;
|
||||
|
||||
public Builder( CallEventType callEventType )
|
||||
@@ -106,7 +106,7 @@ public class P25CallEvent extends CallEvent
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder channel( int channel )
|
||||
public Builder channel( String channel )
|
||||
{
|
||||
mChannel = channel;
|
||||
return this;
|
||||
|
||||
@@ -22,12 +22,21 @@ import alias.Alias;
|
||||
import alias.AliasList;
|
||||
import audio.SquelchListener;
|
||||
import audio.SquelchListener.SquelchState;
|
||||
import controller.activity.CallEvent.CallEventType;
|
||||
import controller.channel.ProcessingChain;
|
||||
import controller.state.AuxChannelState;
|
||||
import controller.state.ChannelState;
|
||||
import decode.p25.message.P25Message;
|
||||
import decode.p25.message.pdu.osp.control.RFSSStatusBroadcastExtended;
|
||||
import decode.p25.message.tsbk.TSBKMessage;
|
||||
import decode.p25.message.tsbk.osp.control.LocationRegistrationResponse;
|
||||
import decode.p25.message.tsbk.osp.control.RFSSStatusBroadcast;
|
||||
import decode.p25.message.tsbk.osp.control.UnitDeregistrationAcknowledge;
|
||||
import decode.p25.message.tsbk.osp.voice.GroupVoiceChannelGrant;
|
||||
import decode.p25.message.tsbk.osp.voice.GroupVoiceChannelGrantUpdate;
|
||||
import decode.p25.message.tsbk.osp.voice.GroupVoiceChannelGrantUpdateExplicit;
|
||||
import decode.p25.message.tsbk.osp.voice.UnitToUnitAnswerRequest;
|
||||
import decode.p25.reference.Vendor;
|
||||
|
||||
public class P25ChannelState extends ChannelState
|
||||
{
|
||||
@@ -123,11 +132,118 @@ public class P25ChannelState extends ChannelState
|
||||
{
|
||||
mSiteAlias = alias.getName();
|
||||
|
||||
broadcastChange( ChangedAttribute.SITE_ALIAS );
|
||||
}
|
||||
else
|
||||
{
|
||||
mSiteAlias = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
broadcastChange( ChangedAttribute.SITE );
|
||||
|
||||
broadcastChange( ChangedAttribute.SITE_ALIAS );
|
||||
}
|
||||
}
|
||||
else if( message instanceof TSBKMessage )
|
||||
{
|
||||
TSBKMessage tsbk = (TSBKMessage)message;
|
||||
|
||||
setState( State.CONTROL );
|
||||
|
||||
if( tsbk.getVendor() == Vendor.STANDARD )
|
||||
{
|
||||
switch( tsbk.getOpcode() )
|
||||
{
|
||||
case GROUP_VOICE_CHANNEL_GRANT:
|
||||
GroupVoiceChannelGrant gvcg = (GroupVoiceChannelGrant)tsbk;
|
||||
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.CALL )
|
||||
.aliasList( mAliasList )
|
||||
.channel( gvcg.getChannelIdentifier() + "-" + gvcg.getChannel() )
|
||||
.details( ( gvcg.isEncrypted() ? "ENCRYPTED" : "" ) +
|
||||
( gvcg.isEmergency() ? " EMERGENCY" : "") )
|
||||
.frequency( gvcg.getDownlinkFrequency() )
|
||||
.from( gvcg.getSourceAddress() )
|
||||
.to( gvcg.getGroupAddress() )
|
||||
.build() );
|
||||
break;
|
||||
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
|
||||
GroupVoiceChannelGrantUpdate gvcgu =
|
||||
(GroupVoiceChannelGrantUpdate)tsbk;
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.CALL )
|
||||
.aliasList( mAliasList )
|
||||
.channel( gvcgu.getChannelID1() + "-" + gvcgu.getChannelNumber1() )
|
||||
.details( ( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
|
||||
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
|
||||
.frequency( gvcgu.getDownlinkFrequency() )
|
||||
.to( gvcgu.getGroupAddress1() )
|
||||
.build() );
|
||||
if( gvcgu.getChannelNumber2() != 0 )
|
||||
{
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.CALL )
|
||||
.aliasList( mAliasList )
|
||||
.channel( gvcgu.getChannelID2() + "-" + gvcgu.getChannelNumber2() )
|
||||
.details( ( gvcgu.isEncrypted() ? "ENCRYPTED" : "" ) +
|
||||
( gvcgu.isEmergency() ? " EMERGENCY" : "") )
|
||||
.frequency( gvcgu.getDownlinkFrequency() )
|
||||
.to( gvcgu.getGroupAddress2() )
|
||||
.build() );
|
||||
}
|
||||
break;
|
||||
case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT:
|
||||
GroupVoiceChannelGrantUpdateExplicit gvcgue =
|
||||
(GroupVoiceChannelGrantUpdateExplicit)tsbk;
|
||||
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.CALL )
|
||||
.aliasList( mAliasList )
|
||||
.channel( gvcgue.getTransmitChannelID() + "-" +
|
||||
gvcgue.getTransmitChannelNumber() )
|
||||
.details( ( gvcgue.isEncrypted() ? "ENCRYPTED" : "" ) +
|
||||
( gvcgue.isEmergency() ? " EMERGENCY" : "") )
|
||||
.frequency( gvcgue.getDownlinkFrequency() )
|
||||
.to( gvcgue.getGroupAddress() )
|
||||
.build() );
|
||||
break;
|
||||
case UNIT_TO_UNIT_ANSWER_REQUEST:
|
||||
UnitToUnitAnswerRequest utuar =
|
||||
(UnitToUnitAnswerRequest)tsbk;
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.PAGE )
|
||||
.aliasList( mAliasList )
|
||||
.details( ( utuar.isEmergency() ? "EMERGENCY" : "" ) )
|
||||
.from( utuar.getSourceAddress() )
|
||||
.to( utuar.getTargetAddress() )
|
||||
.build() );
|
||||
break;
|
||||
case LOCATION_REGISTRATION_RESPONSE:
|
||||
LocationRegistrationResponse lrr =
|
||||
(LocationRegistrationResponse)tsbk;
|
||||
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.REGISTER )
|
||||
.aliasList( mAliasList )
|
||||
.details( "REG:" + lrr.getResponse().name() +
|
||||
" SITE: " + lrr.getRFSSID() + "-" +
|
||||
lrr.getSiteID() )
|
||||
.from( lrr.getTargetAddress() )
|
||||
.to( lrr.getGroupAddress() )
|
||||
.build() );
|
||||
break;
|
||||
case UNIT_DEREGISTRATION_ACKNOWLEDGE:
|
||||
UnitDeregistrationAcknowledge udr =
|
||||
(UnitDeregistrationAcknowledge)tsbk;
|
||||
|
||||
mCallEventModel.add(
|
||||
new P25CallEvent.Builder( CallEventType.DEREGISTER )
|
||||
.aliasList( mAliasList )
|
||||
.from( udr.getSourceID() )
|
||||
.build() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class P25Panel extends ChannelStatePanel
|
||||
|
||||
private JLabel mSystem = new JLabel( "SYS:" );
|
||||
private JLabel mSite = new JLabel( "Site:" );
|
||||
private JLabel mSiteAlias = new JLabel( "WACN:" );
|
||||
private JLabel mSiteAlias = new JLabel( "" );
|
||||
|
||||
|
||||
public P25Panel( Channel channel )
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package decode.p25;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
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 );
|
||||
public final static int MAX_ERROR_THRESHOLD = 7;
|
||||
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( TrellisHalfRate.class );
|
||||
|
||||
private ArrayList<ConstellationNode> mConstellationNodes =
|
||||
new ArrayList<ConstellationNode>();
|
||||
@@ -94,7 +97,7 @@ public class TrellisHalfRate
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void decode( BitSetBuffer message, int start, int end )
|
||||
public boolean decode( BitSetBuffer message, int start, int end )
|
||||
{
|
||||
/* load each of the nodes with de-interleaved constellations */
|
||||
for( int index = 0; index < 49; index++ )
|
||||
@@ -104,20 +107,24 @@ public class TrellisHalfRate
|
||||
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.hasStateDibit( Dibit.D00_PLUS_1 ) || !firstNode.isCorrect() )
|
||||
{
|
||||
firstNode.correctTo( Dibit.D00_PLUS_1 );
|
||||
}
|
||||
int errorCount = firstNode.getErrorCount();
|
||||
|
||||
// mLog.debug( constellationsToString( "CORRECTD: " ) );
|
||||
//
|
||||
// mLog.debug( inputsToString() );
|
||||
//
|
||||
if( errorCount > 0 )
|
||||
{
|
||||
if( errorCount < MAX_ERROR_THRESHOLD )
|
||||
{
|
||||
/* repair the errors */
|
||||
firstNode.correctTo( Dibit.D00_PLUS_1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear constellations from original message */
|
||||
message.clear( start, end );
|
||||
|
||||
@@ -137,6 +144,8 @@ public class TrellisHalfRate
|
||||
message.set( start + ( index * 2 ) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Constellation getConstellation( BitSetBuffer message, int index )
|
||||
@@ -301,24 +310,18 @@ public class TrellisHalfRate
|
||||
* @return - true - all node connections to the right are correct
|
||||
* false - one or more nodes to the right are incorrect
|
||||
*/
|
||||
public boolean isCorrect()
|
||||
public int getErrorCount()
|
||||
{
|
||||
if( mCorrect )
|
||||
{
|
||||
return mCorrect;
|
||||
}
|
||||
|
||||
if( mConnectedNode == null )
|
||||
{
|
||||
mCorrect = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCorrect = mConnectedNode.isCorrect() &&
|
||||
mConstellation.getInput() == mConnectedNode.getStateDibit();
|
||||
}
|
||||
|
||||
mCorrect = mConstellation.getInput() == mConnectedNode.getStateDibit();
|
||||
|
||||
return mCorrect;
|
||||
return mConnectedNode.getErrorCount() + ( mCorrect ? 0 : 1 );
|
||||
}
|
||||
|
||||
public Dibit getStateDibit()
|
||||
@@ -495,15 +498,17 @@ public class TrellisHalfRate
|
||||
*/
|
||||
public static void main( String[] args )
|
||||
{
|
||||
String original = "00100110000001111000101111110011111000011110100111100001000100100010110000001101100100100010001000100010001000101100111000100010111110001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000101100001110000101000110011100001110";
|
||||
|
||||
BitSetBuffer buffer = new BitSetBuffer( original.length() );
|
||||
Random random = new Random();
|
||||
|
||||
BitSetBuffer buffer = new BitSetBuffer( 196 );
|
||||
|
||||
try
|
||||
{
|
||||
for( int x = 0; x < original.length(); x++ )
|
||||
for( int x = 0; x < 196; x++ )
|
||||
{
|
||||
if( original.substring( x, x + 1 ).contentEquals( "0" ) )
|
||||
int number = random.nextInt( 2 );
|
||||
|
||||
if( number == 1 )
|
||||
{
|
||||
buffer.add( false );
|
||||
}
|
||||
@@ -518,12 +523,11 @@ public class TrellisHalfRate
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mLog.debug( "ORIGINAL: " + original );
|
||||
mLog.debug( " BUFFER: " + buffer.toString() );
|
||||
|
||||
TrellisHalfRate t = new TrellisHalfRate();
|
||||
|
||||
t.decode( buffer, 64, original.length() );
|
||||
t.decode( buffer, 0, 196 );
|
||||
mLog.debug( " DECODED: " + buffer.toString() );
|
||||
mLog.debug( "Finished!" );
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class P25MessageFilterSet extends FilterSet<Message>
|
||||
|
||||
addFilter( new PDUMessageFilter() );
|
||||
addFilter( new TDUMessageFilter() );
|
||||
addFilter( new TSBKMessageFilter() );
|
||||
addFilter( new TSBKMessageFilterSet() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package decode.p25.message.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import message.Message;
|
||||
import decode.p25.message.tsbk.TSBKMessage;
|
||||
import decode.p25.reference.Opcode;
|
||||
import filter.Filter;
|
||||
import filter.FilterElement;
|
||||
|
||||
public class TSBKMessageFilter extends Filter<Message>
|
||||
{
|
||||
private HashMap<Opcode,FilterElement<Opcode>> mFilterElements =
|
||||
new HashMap<Opcode,FilterElement<Opcode>>();
|
||||
|
||||
public TSBKMessageFilter()
|
||||
{
|
||||
super( "TSBK Trunking Signalling Block" );
|
||||
|
||||
for( Opcode opcode: Opcode.values() )
|
||||
{
|
||||
mFilterElements.put( opcode, new FilterElement<Opcode>( opcode ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( Message message )
|
||||
{
|
||||
if( mEnabled && canProcess( message ) )
|
||||
{
|
||||
TSBKMessage tsbk = (TSBKMessage)message;
|
||||
|
||||
Opcode opcode = tsbk.getOpcode();
|
||||
|
||||
return mFilterElements.get( opcode ).isEnabled();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( Message message )
|
||||
{
|
||||
return message instanceof TSBKMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterElement<?>> getFilterElements()
|
||||
{
|
||||
return new ArrayList<FilterElement<?>>( mFilterElements.values() );
|
||||
}
|
||||
}
|
||||
200
src/decode/p25/message/filter/TSBKMessageFilterSet.java
Normal file
200
src/decode/p25/message/filter/TSBKMessageFilterSet.java
Normal file
@@ -0,0 +1,200 @@
|
||||
package decode.p25.message.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import message.Message;
|
||||
import decode.p25.message.tsbk.TSBKMessage;
|
||||
import decode.p25.message.tsbk.motorola.MotorolaOpcode;
|
||||
import decode.p25.message.tsbk.vendor.VendorOpcode;
|
||||
import decode.p25.reference.Opcode;
|
||||
import decode.p25.reference.Vendor;
|
||||
import filter.Filter;
|
||||
import filter.FilterElement;
|
||||
import filter.FilterSet;
|
||||
|
||||
public class TSBKMessageFilterSet extends FilterSet<Message>
|
||||
{
|
||||
public TSBKMessageFilterSet()
|
||||
{
|
||||
super( "TSBK Trunking Signalling Block" );
|
||||
|
||||
addFilter( new StandardOpcodeFilter() );
|
||||
addFilter( new MotorolaOpcodeFilter() );
|
||||
addFilter( new VendorOpcodeFilter() );
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean passes( Message message )
|
||||
// {
|
||||
// if( mEnabled && canProcess( message ) )
|
||||
// {
|
||||
// TSBKMessage tsbk = (TSBKMessage)message;
|
||||
//
|
||||
// switch( tsbk.getVendor() )
|
||||
// {
|
||||
// case STANDARD:
|
||||
// return
|
||||
// }
|
||||
// Opcode opcode = tsbk.getOpcode();
|
||||
//
|
||||
// return mFilterElements.get( opcode ).isEnabled();
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean canProcess( Message message )
|
||||
{
|
||||
return message instanceof TSBKMessage;
|
||||
}
|
||||
|
||||
public class StandardOpcodeFilter extends Filter<Message>
|
||||
{
|
||||
private HashMap<Opcode,FilterElement<Opcode>> mStandardElements =
|
||||
new HashMap<Opcode,FilterElement<Opcode>>();
|
||||
|
||||
public StandardOpcodeFilter()
|
||||
{
|
||||
super( "Standard Opcode Filter" );
|
||||
|
||||
for( Opcode opcode: Opcode.values() )
|
||||
{
|
||||
if( opcode != Opcode.UNKNOWN )
|
||||
{
|
||||
mStandardElements.put( opcode,
|
||||
new FilterElement<Opcode>( opcode ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( Message message )
|
||||
{
|
||||
if( mEnabled && canProcess( message ) )
|
||||
{
|
||||
Opcode opcode = ((TSBKMessage)message).getOpcode();
|
||||
|
||||
if( mStandardElements.containsKey( opcode ) )
|
||||
{
|
||||
return mStandardElements.get( opcode ).isEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( Message message )
|
||||
{
|
||||
|
||||
return ((TSBKMessage)message).getVendor() == Vendor.STANDARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterElement<?>> getFilterElements()
|
||||
{
|
||||
return new ArrayList<FilterElement<?>>( mStandardElements.values() );
|
||||
}
|
||||
}
|
||||
|
||||
public class MotorolaOpcodeFilter extends Filter<Message>
|
||||
{
|
||||
private HashMap<MotorolaOpcode,FilterElement<MotorolaOpcode>> mMotorolaElements =
|
||||
new HashMap<MotorolaOpcode,FilterElement<MotorolaOpcode>>();
|
||||
|
||||
public MotorolaOpcodeFilter()
|
||||
{
|
||||
super( "Motorola Opcode Filter" );
|
||||
|
||||
for( MotorolaOpcode opcode: MotorolaOpcode.values() )
|
||||
{
|
||||
if( opcode != MotorolaOpcode.UNKNOWN )
|
||||
{
|
||||
mMotorolaElements.put( opcode,
|
||||
new FilterElement<MotorolaOpcode>( opcode ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( Message message )
|
||||
{
|
||||
if( mEnabled && canProcess( message ) )
|
||||
{
|
||||
MotorolaOpcode opcode = ((TSBKMessage)message).getMotorolaOpcode();
|
||||
|
||||
if( mMotorolaElements.containsKey( opcode ) )
|
||||
{
|
||||
return mMotorolaElements.get( opcode ).isEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( Message message )
|
||||
{
|
||||
return ((TSBKMessage)message).getVendor() == Vendor.MOTOROLA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterElement<?>> getFilterElements()
|
||||
{
|
||||
return new ArrayList<FilterElement<?>>( mMotorolaElements.values() );
|
||||
}
|
||||
}
|
||||
|
||||
public class VendorOpcodeFilter extends Filter<Message>
|
||||
{
|
||||
private HashMap<VendorOpcode,FilterElement<VendorOpcode>> mVendorElements =
|
||||
new HashMap<VendorOpcode,FilterElement<VendorOpcode>>();
|
||||
|
||||
public VendorOpcodeFilter()
|
||||
{
|
||||
super( "Vendor Opcode Filter" );
|
||||
|
||||
for( VendorOpcode opcode: VendorOpcode.values() )
|
||||
{
|
||||
if( opcode != VendorOpcode.UNKNOWN )
|
||||
{
|
||||
mVendorElements.put( opcode,
|
||||
new FilterElement<VendorOpcode>( opcode ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passes( Message message )
|
||||
{
|
||||
if( mEnabled && canProcess( message ) )
|
||||
{
|
||||
MotorolaOpcode opcode = ((TSBKMessage)message).getMotorolaOpcode();
|
||||
|
||||
if( mVendorElements.containsKey( opcode ) )
|
||||
{
|
||||
return mVendorElements.get( opcode ).isEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess( Message message )
|
||||
{
|
||||
Vendor vendor = ((TSBKMessage)message).getVendor();
|
||||
|
||||
return vendor != Vendor.STANDARD && vendor != Vendor.MOTOROLA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterElement<?>> getFilterElements()
|
||||
{
|
||||
return new ArrayList<FilterElement<?>>( mVendorElements.values() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,20 @@ package decode.p25.message.tsbk;
|
||||
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
|
||||
import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
|
||||
public abstract class ChannelGrant extends ServiceMessage
|
||||
public abstract class ChannelGrant extends ServiceMessage
|
||||
implements IdentifierUpdateReceiver
|
||||
{
|
||||
public static final int[] PRIORITY = { 85,86,87 };
|
||||
public static final int[] CHANNEL_ID = { 88,89,90,91 };
|
||||
public static final int[] CHANNEL_NUMBER = { 92,93,94,95,96,97,98,99,100,
|
||||
101,102,103 };
|
||||
|
||||
private IdentifierUpdate mIdentifierUpdate;
|
||||
|
||||
public ChannelGrant( BitSetBuffer message,
|
||||
DataUnitID duid,
|
||||
AliasList aliasList )
|
||||
@@ -26,13 +31,40 @@ public abstract class ChannelGrant extends ServiceMessage
|
||||
return mMessage.getInt( PRIORITY );
|
||||
}
|
||||
|
||||
public int getChannelID()
|
||||
public int getChannelIdentifier()
|
||||
{
|
||||
return mMessage.getInt( CHANNEL_ID );
|
||||
}
|
||||
|
||||
public int getChannelNumber()
|
||||
public int getChannel()
|
||||
{
|
||||
return mMessage.getInt( CHANNEL_NUMBER );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setIdentifierMessage( int identifier, IdentifierUpdate message )
|
||||
{
|
||||
mIdentifierUpdate = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIdentifiers()
|
||||
{
|
||||
int[] identifiers = new int[ 1 ];
|
||||
identifiers[ 0 ] = getChannelIdentifier();
|
||||
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
public long getDownlinkFrequency()
|
||||
{
|
||||
return calculateDownlink( mIdentifierUpdate, getChannel() );
|
||||
}
|
||||
|
||||
public long getUplinkFrequency()
|
||||
{
|
||||
return calculateUplink( mIdentifierUpdate, getChannel() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,15 +41,19 @@ public abstract class GroupChannelGrant extends ChannelGrant
|
||||
sb.append( " EMERGENCY" );
|
||||
}
|
||||
|
||||
sb.append( " CHAN:" );
|
||||
sb.append( getChannelID() + "/" + getChannelNumber() );
|
||||
|
||||
sb.append( " FROM:" );
|
||||
sb.append( " SOURCE UNIT:" );
|
||||
sb.append( getSourceAddress() );
|
||||
|
||||
sb.append( " GRP:" );
|
||||
sb.append( " GROUP:" );
|
||||
sb.append( getGroupAddress() );
|
||||
|
||||
sb.append( " CHAN:" );
|
||||
sb.append( getChannelIdentifier() + "-" + getChannel() );
|
||||
|
||||
sb.append( " DN:" + getDownlinkFrequency() );
|
||||
|
||||
sb.append( " UP:" + getUplinkFrequency() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package decode.p25.message.tsbk;
|
||||
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
|
||||
public abstract class GroupChannelGrantExplicit extends ChannelGrant
|
||||
@@ -15,6 +16,9 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant
|
||||
public static final int[] GROUP_ADDRESS = { 128,129,130,131,132,133,134,135,
|
||||
136,137,138,139,140,141,142,143 };
|
||||
|
||||
private IdentifierUpdate mTransmitIdentifierUpdate;
|
||||
private IdentifierUpdate mReceiveIdentifierUpdate;
|
||||
|
||||
public GroupChannelGrantExplicit( BitSetBuffer message,
|
||||
DataUnitID duid,
|
||||
AliasList aliasList )
|
||||
@@ -69,4 +73,38 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant
|
||||
{
|
||||
return mMessage.getHex( GROUP_ADDRESS, 4 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifierMessage( int identifier, IdentifierUpdate message )
|
||||
{
|
||||
if( identifier == getTransmitChannelID() )
|
||||
{
|
||||
mTransmitIdentifierUpdate = message;
|
||||
}
|
||||
|
||||
if( identifier == getReceiveChannelID() )
|
||||
{
|
||||
mReceiveIdentifierUpdate = message;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIdentifiers()
|
||||
{
|
||||
int[] identifiers = new int[ 2 ];
|
||||
identifiers[ 0 ] = getTransmitChannelID();
|
||||
identifiers[ 1 ] = getReceiveChannelID();
|
||||
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
public long getDownlinkFrequency()
|
||||
{
|
||||
return calculateDownlink( mTransmitIdentifierUpdate, getChannel() );
|
||||
}
|
||||
|
||||
public long getUplinkFrequency()
|
||||
{
|
||||
return calculateUplink( mReceiveIdentifierUpdate, getChannel() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ package decode.p25.message.tsbk;
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.P25Message;
|
||||
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
|
||||
import decode.p25.message.tsbk.motorola.MotorolaOpcode;
|
||||
import decode.p25.message.tsbk.vendor.VendorOpcode;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
import decode.p25.reference.Opcode;
|
||||
import decode.p25.reference.Vendor;
|
||||
@@ -56,6 +57,16 @@ public class TSBKMessage extends P25Message
|
||||
return Opcode.fromValue( mMessage.getInt( OPCODE ) );
|
||||
}
|
||||
|
||||
public MotorolaOpcode getMotorolaOpcode()
|
||||
{
|
||||
return MotorolaOpcode.fromValue( mMessage.getInt( OPCODE ) );
|
||||
}
|
||||
|
||||
public VendorOpcode getVendorOpcode()
|
||||
{
|
||||
return VendorOpcode.fromValue( mMessage.getInt( OPCODE ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
|
||||
@@ -196,9 +196,9 @@ public class TSBKMessageFactory
|
||||
|
||||
switch( motorolaOpcode )
|
||||
{
|
||||
case CHANNEL_CWID_UPDATE:
|
||||
case OP0B:
|
||||
return new ChannelCWIDUpdate( message, duid, aliasList );
|
||||
case SYSTEM_LOADING:
|
||||
case OP09:
|
||||
return new SystemLoading( message, duid, aliasList );
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ChannelCWIDUpdate extends MotorolaTSBKMessage
|
||||
@Override
|
||||
public String getEventType()
|
||||
{
|
||||
return MotorolaOpcode.CHANNEL_CWID_UPDATE.getDescription();
|
||||
return MotorolaOpcode.OP0B.getDescription();
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
@@ -58,94 +58,31 @@ public class ChannelCWIDUpdate extends MotorolaTSBKMessage
|
||||
public String getCWID()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int char1 = mMessage.getInt( CHARACTER_1 );
|
||||
|
||||
if( char1 != 0 )
|
||||
{
|
||||
sb.append( (char)( char1 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int char2 = mMessage.getInt( CHARACTER_2 );
|
||||
|
||||
if( char2 != 0 )
|
||||
{
|
||||
sb.append( (char)( char2 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char3 = mMessage.getInt( CHARACTER_3 );
|
||||
|
||||
if( char3 != 0 )
|
||||
{
|
||||
sb.append( (char)( char3 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char4 = mMessage.getInt( CHARACTER_4 );
|
||||
|
||||
if( char4 != 0 )
|
||||
{
|
||||
sb.append( (char)( char4 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char5 = mMessage.getInt( CHARACTER_5 );
|
||||
|
||||
if( char5 != 0 )
|
||||
{
|
||||
sb.append( (char)( char5 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char6 = mMessage.getInt( CHARACTER_6 );
|
||||
|
||||
if( char6 != 0 )
|
||||
{
|
||||
sb.append( (char)( char6 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char7 = mMessage.getInt( CHARACTER_7 );
|
||||
|
||||
if( char7 != 0 )
|
||||
{
|
||||
sb.append( (char)( char7 + 46 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
int char8 = mMessage.getInt( CHARACTER_8 );
|
||||
|
||||
if( char8 != 0 )
|
||||
{
|
||||
sb.append( (char)( char8 + 46 ) );
|
||||
}
|
||||
sb.append( getCharacter( CHARACTER_1 ) );
|
||||
sb.append( getCharacter( CHARACTER_2 ) );
|
||||
sb.append( getCharacter( CHARACTER_3 ) );
|
||||
sb.append( getCharacter( CHARACTER_4 ) );
|
||||
sb.append( getCharacter( CHARACTER_5 ) );
|
||||
sb.append( getCharacter( CHARACTER_6 ) );
|
||||
sb.append( getCharacter( CHARACTER_7 ) );
|
||||
sb.append( getCharacter( CHARACTER_8 ) );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String getCharacter( int[] field )
|
||||
{
|
||||
int value = mMessage.getInt( field );
|
||||
|
||||
if( value != 0 )
|
||||
{
|
||||
return String.valueOf( (char)( value + 43 ) );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getIdentifier()
|
||||
{
|
||||
return mMessage.getInt( IDENTIFIER );
|
||||
|
||||
@@ -2,9 +2,70 @@ package decode.p25.message.tsbk.motorola;
|
||||
|
||||
public enum MotorolaOpcode
|
||||
{
|
||||
UNKNOWN_OPCODE_5( "MOTO OPCODE 05 ", "Unknown Opcode 0x05", 0x05 ),
|
||||
SYSTEM_LOADING( "SYSTEM_LOADING ", "System Loading", 0x09 ),
|
||||
CHANNEL_CWID_UPDATE( "CHAN_CWID_UPDATE", "Channel FCC Callsign Update", 0x0B ),
|
||||
OP00( "OP00:UNKNOWN ", "Opcode 0x00 Unknown", 0x00 ),
|
||||
OP01( "OP01:UNKNOWN ", "Opcode 0x01 Unknown", 0x01 ),
|
||||
OP02( "OP02:UNKNOWN ", "Opcode 0x02 Unknown", 0x02 ),
|
||||
OP03( "OP03:UNKNOWN ", "Opcode 0x03 Unknown", 0x03 ),
|
||||
OP04( "OP04:UNKNOWN ", "Opcode 0x04 Unknown", 0x04 ),
|
||||
OP05( "OP05:UNKNOWN ", "Opcode 0x05 Unknown", 0x05 ),
|
||||
OP06( "OP06:UNKNOWN ", "Opcode 0x06 Unknown", 0x06 ),
|
||||
OP07( "OP07:UNKNOWN ", "Opcode 0x07 Unknown", 0x07 ),
|
||||
OP08( "OP08:UNKNOWN ", "Opcode 0x08 Unknown", 0x08 ),
|
||||
OP09( "OP09:SYSTEM_LOAD", "Opcode 0x09 System Loading", 0x09 ),
|
||||
OP0A( "OP0A:UNKNOWN ", "Opcode 0x0A Unknown", 0x0A ),
|
||||
OP0B( "OP0B:CWID_UPDATE", "Opcode 0x0B FCC Callsign", 0x0B ),
|
||||
OP0C( "OP0C:UNKNOWN ", "Opcode 0x0C Unknown", 0x0C ),
|
||||
OP0D( "OP0D:UNKNOWN ", "Opcode 0x0D Unknown", 0x0D ),
|
||||
OP0E( "OP0E:UNKNOWN ", "Opcode 0x0E Unknown", 0x0E ),
|
||||
OP0F( "OP0F:UNKNOWN ", "Opcode 0x0F Unknown", 0x0F ),
|
||||
OP10( "OP10:UNKNOWN ", "Opcode 0x10 Unknown", 0x10 ),
|
||||
OP11( "OP11:UNKNOWN ", "Opcode 0x11 Unknown", 0x11 ),
|
||||
OP12( "OP12:UNKNOWN ", "Opcode 0x12 Unknown", 0x12 ),
|
||||
OP13( "OP13:UNKNOWN ", "Opcode 0x13 Unknown", 0x13 ),
|
||||
OP14( "OP14:UNKNOWN ", "Opcode 0x14 Unknown", 0x14 ),
|
||||
OP15( "OP15:UNKNOWN ", "Opcode 0x15 Unknown", 0x15 ),
|
||||
OP16( "OP16:UNKNOWN ", "Opcode 0x16 Unknown", 0x16 ),
|
||||
OP17( "OP17:UNKNOWN ", "Opcode 0x17 Unknown", 0x17 ),
|
||||
OP18( "OP18:UNKNOWN ", "Opcode 0x18 Unknown", 0x18 ),
|
||||
OP19( "OP19:UNKNOWN ", "Opcode 0x19 Unknown", 0x19 ),
|
||||
OP1A( "OP1A:UNKNOWN ", "Opcode 0x1A Unknown", 0x1A ),
|
||||
OP1B( "OP1B:UNKNOWN ", "Opcode 0x1B Unknown", 0x1B ),
|
||||
OP1C( "OP1C:UNKNOWN ", "Opcode 0x1C Unknown", 0x1C ),
|
||||
OP1D( "OP1D:UNKNOWN ", "Opcode 0x1D Unknown", 0x1D ),
|
||||
OP1E( "OP1E:UNKNOWN ", "Opcode 0x1E Unknown", 0x1E ),
|
||||
OP1F( "OP1F:UNKNOWN ", "Opcode 0x1F Unknown", 0x1F ),
|
||||
OP20( "OP20:UNKNOWN ", "Opcode 0x20 Unknown", 0x20 ),
|
||||
OP21( "OP21:UNKNOWN ", "Opcode 0x21 Unknown", 0x21 ),
|
||||
OP22( "OP22:UNKNOWN ", "Opcode 0x22 Unknown", 0x22 ),
|
||||
OP23( "OP23:UNKNOWN ", "Opcode 0x23 Unknown", 0x23 ),
|
||||
OP24( "OP24:UNKNOWN ", "Opcode 0x24 Unknown", 0x24 ),
|
||||
OP25( "OP25:UNKNOWN ", "Opcode 0x25 Unknown", 0x25 ),
|
||||
OP26( "OP26:UNKNOWN ", "Opcode 0x26 Unknown", 0x26 ),
|
||||
OP27( "OP27:UNKNOWN ", "Opcode 0x27 Unknown", 0x27 ),
|
||||
OP28( "OP28:UNKNOWN ", "Opcode 0x28 Unknown", 0x28 ),
|
||||
OP29( "OP29:UNKNOWN ", "Opcode 0x29 Unknown", 0x29 ),
|
||||
OP2A( "OP2A:UNKNOWN ", "Opcode 0x2A Unknown", 0x2A ),
|
||||
OP2B( "OP2B:UNKNOWN ", "Opcode 0x2B Unknown", 0x2B ),
|
||||
OP2C( "OP2C:UNKNOWN ", "Opcode 0x2C Unknown", 0x2C ),
|
||||
OP2D( "OP2D:UNKNOWN ", "Opcode 0x2D Unknown", 0x2D ),
|
||||
OP2E( "OP2E:UNKNOWN ", "Opcode 0x2E Unknown", 0x2E ),
|
||||
OP2F( "OP2F:UNKNOWN ", "Opcode 0x2F Unknown", 0x2F ),
|
||||
OP30( "OP30:UNKNOWN ", "Opcode 0x30 Unknown", 0x30 ),
|
||||
OP31( "OP31:UNKNOWN ", "Opcode 0x31 Unknown", 0x31 ),
|
||||
OP32( "OP32:UNKNOWN ", "Opcode 0x32 Unknown", 0x32 ),
|
||||
OP33( "OP33:UNKNOWN ", "Opcode 0x33 Unknown", 0x33 ),
|
||||
OP34( "OP34:UNKNOWN ", "Opcode 0x34 Unknown", 0x34 ),
|
||||
OP35( "OP35:UNKNOWN ", "Opcode 0x35 Unknown", 0x35 ),
|
||||
OP36( "OP36:UNKNOWN ", "Opcode 0x36 Unknown", 0x36 ),
|
||||
OP37( "OP37:UNKNOWN ", "Opcode 0x37 Unknown", 0x37 ),
|
||||
OP38( "OP38:UNKNOWN ", "Opcode 0x38 Unknown", 0x38 ),
|
||||
OP39( "OP39:UNKNOWN ", "Opcode 0x39 Unknown", 0x39 ),
|
||||
OP3A( "OP3A:UNKNOWN ", "Opcode 0x3A Unknown", 0x3A ),
|
||||
OP3B( "OP3B:UNKNOWN ", "Opcode 0x3B Unknown", 0x3B ),
|
||||
OP3C( "OP3C:UNKNOWN ", "Opcode 0x3C Unknown", 0x3C ),
|
||||
OP3D( "OP3D:UNKNOWN ", "Opcode 0x3D Unknown", 0x3D ),
|
||||
OP3E( "OP3E:UNKNOWN ", "Opcode 0x3E Unknown", 0x3E ),
|
||||
OP3F( "OP3F:UNKNOWN ", "Opcode 0x3F Unknown", 0x3F ),
|
||||
UNKNOWN( "UNKNOWN ", "Unknown", -1 );
|
||||
|
||||
private String mLabel;
|
||||
@@ -23,6 +84,11 @@ public enum MotorolaOpcode
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getLabel();
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return mDescription;
|
||||
@@ -35,14 +101,9 @@ public enum MotorolaOpcode
|
||||
|
||||
public static MotorolaOpcode fromValue( int value )
|
||||
{
|
||||
switch( value )
|
||||
if( 0 <= value && value <= 0x3F )
|
||||
{
|
||||
case 0x05:
|
||||
return UNKNOWN_OPCODE_5;
|
||||
case 0x09:
|
||||
return SYSTEM_LOADING;
|
||||
case 0x0B:
|
||||
return CHANNEL_CWID_UPDATE;
|
||||
return MotorolaOpcode.values()[ value ];
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
|
||||
@@ -16,7 +16,7 @@ public class SystemLoading extends MotorolaTSBKMessage
|
||||
@Override
|
||||
public String getEventType()
|
||||
{
|
||||
return MotorolaOpcode.SYSTEM_LOADING.getLabel();
|
||||
return MotorolaOpcode.OP09.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,7 +52,7 @@ public class LocationRegistrationResponse extends TSBKMessage
|
||||
|
||||
public String getGroupAddress()
|
||||
{
|
||||
return mMessage.getHex( GROUP_ADDRESS, 6 );
|
||||
return mMessage.getHex( GROUP_ADDRESS, 4 );
|
||||
}
|
||||
|
||||
public String getRFSSID()
|
||||
|
||||
@@ -54,7 +54,8 @@ public class TimeAndDateAnnouncement extends TSBKMessage
|
||||
{
|
||||
sb.append( " DATE-TIME:" );
|
||||
}
|
||||
|
||||
|
||||
sb.append( " " );
|
||||
sb.append( mTimeFormatter.format( new Date( getDateTimestamp() ) ) );
|
||||
|
||||
return sb.toString();
|
||||
|
||||
@@ -20,4 +20,5 @@ public class GroupVoiceChannelGrant extends GroupChannelGrant
|
||||
{
|
||||
return Opcode.GROUP_VOICE_CHANNEL_GRANT.getDescription();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class TelephoneInterconnectVoiceChannelGrant extends UnitChannelGrant
|
||||
}
|
||||
|
||||
sb.append( " CHAN:" );
|
||||
sb.append( getChannelID() + "/" + getChannelNumber() );
|
||||
sb.append( getChannelIdentifier() + "/" + getChannel() );
|
||||
|
||||
sb.append( " CALL TIMER:" );
|
||||
sb.append( getCallTimer() );
|
||||
|
||||
@@ -3,6 +3,7 @@ package decode.p25.message.tsbk.osp.voice;
|
||||
import alias.AliasList;
|
||||
import bits.BitSetBuffer;
|
||||
import decode.p25.message.tsbk.UnitChannelGrant;
|
||||
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
|
||||
import decode.p25.reference.DataUnitID;
|
||||
import decode.p25.reference.Opcode;
|
||||
|
||||
@@ -20,4 +21,28 @@ public class UnitToUnitVoiceChannelGrant extends UnitChannelGrant
|
||||
{
|
||||
return Opcode.UNIT_TO_UNIT_VOICE_CHANNEL_GRANT.getDescription();
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append( getMessageStub() );
|
||||
|
||||
if( isEmergency() )
|
||||
{
|
||||
sb.append( " EMERGENCY" );
|
||||
}
|
||||
|
||||
sb.append( " SOURCE UNIT:" );
|
||||
sb.append( getSourceAddress() );
|
||||
|
||||
sb.append( " TARGET UNIT:" );
|
||||
sb.append( getTargetAddress() );
|
||||
|
||||
sb.append( " CHAN:" + getChannelIdentifier() + "-" + getChannel() );
|
||||
sb.append( " DN:" + getDownlinkFrequency() );
|
||||
sb.append( " UP:" + getUplinkFrequency() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
111
src/decode/p25/message/tsbk/vendor/VendorOpcode.java
vendored
Normal file
111
src/decode/p25/message/tsbk/vendor/VendorOpcode.java
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
package decode.p25.message.tsbk.vendor;
|
||||
|
||||
public enum VendorOpcode
|
||||
{
|
||||
OP00( "OPCODE 00 ", "VENDOR OPCODE 0x00", 0x00 ),
|
||||
OP01( "OPCODE 01 ", "VENDOR OPCODE 0x01", 0x01 ),
|
||||
OP02( "OPCODE 02 ", "VENDOR OPCODE 0x02", 0x02 ),
|
||||
OP03( "OPCODE 03 ", "VENDOR OPCODE 0x03", 0x03 ),
|
||||
OP04( "OPCODE 04 ", "VENDOR OPCODE 0x04", 0x04 ),
|
||||
OP05( "OPCODE 05 ", "VENDOR OPCODE 0x05", 0x05 ),
|
||||
OP06( "OPCODE 06 ", "VENDOR OPCODE 0x06", 0x06 ),
|
||||
OP07( "OPCODE 07 ", "VENDOR OPCODE 0x07", 0x07 ),
|
||||
OP08( "OPCODE 08 ", "VENDOR OPCODE 0x08", 0x08 ),
|
||||
OP09( "OPCODE 09 ", "VENDOR OPCODE 0x09", 0x09 ),
|
||||
OP0A( "OPCODE 0A ", "VENDOR OPCODE 0x0A", 0x0A ),
|
||||
OP0B( "OPCODE 0B ", "VENDOR OPCODE 0x0B", 0x0B ),
|
||||
OP0C( "OPCODE 0C ", "VENDOR OPCODE 0x0C", 0x0C ),
|
||||
OP0D( "OPCODE 0D ", "VENDOR OPCODE 0x0D", 0x0D ),
|
||||
OP0E( "OPCODE 0E ", "VENDOR OPCODE 0x0E", 0x0E ),
|
||||
OP0F( "OPCODE 0F ", "VENDOR OPCODE 0x0F", 0x0F ),
|
||||
OP10( "OPCODE 10 ", "VENDOR OPCODE 0x10", 0x10 ),
|
||||
OP11( "OPCODE 11 ", "VENDOR OPCODE 0x11", 0x11 ),
|
||||
OP12( "OPCODE 12 ", "VENDOR OPCODE 0x12", 0x12 ),
|
||||
OP13( "OPCODE 13 ", "VENDOR OPCODE 0x13", 0x13 ),
|
||||
OP14( "OPCODE 14 ", "VENDOR OPCODE 0x14", 0x14 ),
|
||||
OP15( "OPCODE 15 ", "VENDOR OPCODE 0x15", 0x15 ),
|
||||
OP16( "OPCODE 16 ", "VENDOR OPCODE 0x16", 0x16 ),
|
||||
OP17( "OPCODE 17 ", "VENDOR OPCODE 0x17", 0x17 ),
|
||||
OP18( "OPCODE 18 ", "VENDOR OPCODE 0x18", 0x18 ),
|
||||
OP19( "OPCODE 19 ", "VENDOR OPCODE 0x19", 0x19 ),
|
||||
OP1A( "OPCODE 1A ", "VENDOR OPCODE 0x1A", 0x1A ),
|
||||
OP1B( "OPCODE 1B ", "VENDOR OPCODE 0x1B", 0x1B ),
|
||||
OP1C( "OPCODE 1C ", "VENDOR OPCODE 0x1C", 0x1C ),
|
||||
OP1D( "OPCODE 1D ", "VENDOR OPCODE 0x1D", 0x1D ),
|
||||
OP1E( "OPCODE 1E ", "VENDOR OPCODE 0x1E", 0x1E ),
|
||||
OP1F( "OPCODE 1F ", "VENDOR OPCODE 0x1F", 0x1F ),
|
||||
OP20( "OPCODE 20 ", "VENDOR OPCODE 0x20", 0x20 ),
|
||||
OP21( "OPCODE 21 ", "VENDOR OPCODE 0x21", 0x21 ),
|
||||
OP22( "OPCODE 22 ", "VENDOR OPCODE 0x22", 0x22 ),
|
||||
OP23( "OPCODE 23 ", "VENDOR OPCODE 0x23", 0x23 ),
|
||||
OP24( "OPCODE 24 ", "VENDOR OPCODE 0x24", 0x24 ),
|
||||
OP25( "OPCODE 25 ", "VENDOR OPCODE 0x25", 0x25 ),
|
||||
OP26( "OPCODE 26 ", "VENDOR OPCODE 0x26", 0x26 ),
|
||||
OP27( "OPCODE 27 ", "VENDOR OPCODE 0x27", 0x27 ),
|
||||
OP28( "OPCODE 28 ", "VENDOR OPCODE 0x28", 0x28 ),
|
||||
OP29( "OPCODE 29 ", "VENDOR OPCODE 0x29", 0x29 ),
|
||||
OP2A( "OPCODE 2A ", "VENDOR OPCODE 0x2A", 0x2A ),
|
||||
OP2B( "OPCODE 2B ", "VENDOR OPCODE 0x2B", 0x2B ),
|
||||
OP2C( "OPCODE 2C ", "VENDOR OPCODE 0x2C", 0x2C ),
|
||||
OP2D( "OPCODE 2D ", "VENDOR OPCODE 0x2D", 0x2D ),
|
||||
OP2E( "OPCODE 2E ", "VENDOR OPCODE 0x2E", 0x2E ),
|
||||
OP2F( "OPCODE 2F ", "VENDOR OPCODE 0x2F", 0x2F ),
|
||||
OP30( "OPCODE 30 ", "VENDOR OPCODE 0x30", 0x30 ),
|
||||
OP31( "OPCODE 31 ", "VENDOR OPCODE 0x31", 0x31 ),
|
||||
OP32( "OPCODE 32 ", "VENDOR OPCODE 0x32", 0x32 ),
|
||||
OP33( "OPCODE 33 ", "VENDOR OPCODE 0x33", 0x33 ),
|
||||
OP34( "OPCODE 34 ", "VENDOR OPCODE 0x34", 0x34 ),
|
||||
OP35( "OPCODE 35 ", "VENDOR OPCODE 0x35", 0x35 ),
|
||||
OP36( "OPCODE 36 ", "VENDOR OPCODE 0x36", 0x36 ),
|
||||
OP37( "OPCODE 37 ", "VENDOR OPCODE 0x37", 0x37 ),
|
||||
OP38( "OPCODE 38 ", "VENDOR OPCODE 0x38", 0x38 ),
|
||||
OP39( "OPCODE 39 ", "VENDOR OPCODE 0x39", 0x39 ),
|
||||
OP3A( "OPCODE 3A ", "VENDOR OPCODE 0x3A", 0x3A ),
|
||||
OP3B( "OPCODE 3B ", "VENDOR OPCODE 0x3B", 0x3B ),
|
||||
OP3C( "OPCODE 3C ", "VENDOR OPCODE 0x3C", 0x3C ),
|
||||
OP3D( "OPCODE 3D ", "VENDOR OPCODE 0x3D", 0x3D ),
|
||||
OP3E( "OPCODE 3E ", "VENDOR OPCODE 0x3E", 0x3E ),
|
||||
OP3F( "OPCODE 3F ", "VENDOR OPCODE 0x3F", 0x3F ),
|
||||
UNKNOWN( "UNKNOWN ", "Unknown", -1 );
|
||||
|
||||
private String mLabel;
|
||||
private String mDescription;
|
||||
private int mCode;
|
||||
|
||||
private VendorOpcode( String label, String description, int code )
|
||||
{
|
||||
mLabel = label;
|
||||
mDescription = description;
|
||||
mCode = code;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getLabel();
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return mCode;
|
||||
}
|
||||
|
||||
public static VendorOpcode fromValue( int value )
|
||||
{
|
||||
if( 0 <= value && value <= 0x3F )
|
||||
{
|
||||
return VendorOpcode.values()[ value ];
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,13 @@ package decode.p25.reference;
|
||||
|
||||
public enum ServiceAccessPoint
|
||||
{
|
||||
SAP_0( "0", 0 ),
|
||||
SAP_1( "1", 1 ),
|
||||
SAP_2( "2", 2 ),
|
||||
SAP_3( "3", 3 ),
|
||||
SAP_4( "4", 4 ),
|
||||
SAP_5( "5", 5 ),
|
||||
SAP_6( "6", 6 ),
|
||||
UNENCRYPTED_USER_DATA( "0", 0 ),
|
||||
ENCRYPTED_USER_DATA( "1", 1 ),
|
||||
CIRCUIT_DATA( "2", 2 ),
|
||||
CIRCUIT_DATA_CONTROL( "3", 3 ),
|
||||
PACKET_DATA( "4", 4 ),
|
||||
ADDRESS_RESOLUTION_PROTOCOL( "5", 5 ),
|
||||
SNDCP_PACKET_DATA_CONTROL( "6", 6 ),
|
||||
SAP_7( "7", 7 ),
|
||||
SAP_8( "8", 8 ),
|
||||
SAP_9( "9", 9 ),
|
||||
@@ -33,17 +33,17 @@ public enum ServiceAccessPoint
|
||||
SAP_28( "28", 28 ),
|
||||
SAP_29( "29", 29 ),
|
||||
SAP_30( "30", 30 ),
|
||||
SAP_31( "31", 31 ),
|
||||
SAP_32( "32", 32 ),
|
||||
SAP_33( "33", 33 ),
|
||||
SAP_34( "34", 34 ),
|
||||
SAP_35( "35", 35 ),
|
||||
SAP_36( "36", 36 ),
|
||||
SAP_37( "37", 37 ),
|
||||
SAP_38( "38", 38 ),
|
||||
SAP_39( "39", 39 ),
|
||||
SAP_40( "40", 40 ),
|
||||
SAP_41( "41", 41 ),
|
||||
EXTENDED_ADDRESS( "31", 31 ),
|
||||
REGISTRATION_AND_AUTHORIZATION( "32", 32 ),
|
||||
CHANNEL_REASSIGNMENT( "33", 33 ),
|
||||
SYSTEM_CONFIGURATION( "34", 34 ),
|
||||
MR_LOOPBACK( "35", 35 ),
|
||||
MR_STATISTICS( "36", 36 ),
|
||||
MR_OUT_OF_SERVICE( "37", 37 ),
|
||||
MR_PAGING( "38", 38 ),
|
||||
MR_CONFIGURATION( "39", 39 ),
|
||||
UNENCRYPTED_KEY_MANAGEMENT_MESSAGE( "40", 40 ),
|
||||
ENCRYPTED_KEY_MANAGEMENT_MESSAGE( "41", 41 ),
|
||||
SAP_42( "42", 42 ),
|
||||
SAP_43( "43", 43 ),
|
||||
SAP_44( "44", 44 ),
|
||||
|
||||
Reference in New Issue
Block a user