P25 More work in progress

This commit is contained in:
dennis.sheirer
2014-11-17 01:42:07 +00:00
parent ea9741d510
commit def5f9ed6f
19 changed files with 1052 additions and 105 deletions

View File

@@ -450,28 +450,14 @@ public class TrellisHalfRate
*/
public static void main( String[] args )
{
String original = "0010101110101010001011001100111011001000100000101101001000100000110010111010100100100111100100100010000000001110001110010010110000010110001000101101101001110010001001011100001101011110110110011011";
// String original = "0010111110111110001000100010001011000000000000001101101010101001110011011001001000101100000011100010001000101100001101010010001000011010011100001101100111001110000101111101010001101010101001111110";
// String original = "0010001011000000110101111110001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010111110111110110000110101001011110101";
String witherrors = "0010001011000000110101100110001000100010001100100011001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010111110111110110000110101001011110101";
//Injected errors: xx x x
String original = "00100110000001111000101111110011111000011110100111100001000100100010001011000000110101111110001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010111110111110110000110101001011110101";
BitSetBuffer bufferOriginal = new BitSetBuffer( 196 );
BitSetBuffer bufferWithErrors = new BitSetBuffer( 196 );
BitSetBuffer bufferOriginal = new BitSetBuffer( 260 );
try
{
for( int x = 0; x < 196; x++ )
for( int x = 0; x < 260; x++ )
{
if( witherrors.substring( x, x + 1 ).contentEquals( "0" ) )
{
bufferWithErrors.add( false );
}
else
{
bufferWithErrors.add( true );
}
if( original.substring( x, x + 1 ).contentEquals( "0" ) )
{
bufferOriginal.add( false );
@@ -488,15 +474,11 @@ public class TrellisHalfRate
}
System.out.println( " ORIGINAL: " + original );
System.out.println( " WITH ERRORS: " + witherrors );
TrellisHalfRate t = new TrellisHalfRate();
t.decode( bufferOriginal, 0, 196 );
t.decode( bufferOriginal, 64, 260 );
System.out.println( "ORIG DECODED: " + bufferOriginal.toString() );
t.decode( bufferWithErrors, 0, 196 );
System.out.println( "ERRS DECODED: " + bufferWithErrors.toString() );
}
}

View File

@@ -13,6 +13,20 @@ public class TSBKMessage extends P25Message
public static final int ENCRYPTED_FLAG = 65;
public static final int[] OPCODE = { 66,67,68,69,70,71 };
public static final int[] VENDOR_ID = { 72,73,74,75,76,77,78,79 };
public static final int[] BLOCK1 = { 64,65,66,67,68,69,70,71 };
public static final int[] BLOCK2 = { 72,73,74,75,76,77,78,79 };
public static final int[] BLOCK3 = { 80,81,82,83,84,85,86,87 };
public static final int[] BLOCK4 = { 88,89,90,91,92,93,94,95 };
public static final int[] BLOCK5 = { 96,97,98,99,100,101,102,103 };
public static final int[] BLOCK6 = { 104,105,106,107,108,109,110,111 };
public static final int[] BLOCK7 = { 112,113,114,115,116,117,118,119 };
public static final int[] BLOCK8 = { 120,121,122,123,124,125,126,127 };
public static final int[] BLOCK9 = { 128,129,130,131,132,133,134,135 };
public static final int[] BLOCK10 = { 136,137,138,139,140,141,142,143 };
public static final int[] BLOCK11 = { 144,145,146,147,148,149,150,151 };
public static final int[] BLOCK12 = { 152,153,154,155,156,157,158,159 };
public static final int[] CRC = { 144,145,146,147,148,149,150,151,152,153,
154,155,156,157,158,159 };
@@ -45,27 +59,43 @@ public class TSBKMessage extends P25Message
public String getMessage()
{
StringBuilder sb = new StringBuilder();
Vendor vendor = getVendor();
sb.append( "SYSTEM:" );
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( getVendor().getLabel() );
sb.append( vendor.getLabel() );
if( isEncrypted() )
{
sb.append( " ENCRYPTED" );
}
else
{
Opcode opcode = getOpcode();
sb.append( " OPCODE:" );
sb.append( opcode.name() );
sb.append( " [" );
sb.append( mMessage.getHex( OPCODE, 2 ) );
sb.append( "]" );
}
sb.append( " " + getMessageHex() );
return sb.toString();
}
public String getMessageHex()
{
StringBuilder sb = new StringBuilder();
sb.append( mMessage.getHex( BLOCK1, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK2, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK3, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK4, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK5, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK6, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK7, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK8, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK9, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK10, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK11, 2 ) + " " );
sb.append( mMessage.getHex( BLOCK12, 2 ) + " " );
return sb.toString();
}
}

View File

@@ -11,9 +11,20 @@ import decode.p25.message.tsbk.osp.control.ExtendedFunctionCommand;
import decode.p25.message.tsbk.osp.control.GroupAffiliationQuery;
import decode.p25.message.tsbk.osp.control.GroupAffiliationResponse;
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
import decode.p25.message.tsbk.osp.control.LocationRegistrationResponse;
import decode.p25.message.tsbk.osp.control.MessageUpdate;
import decode.p25.message.tsbk.osp.control.NetworkStatusBroadcast;
import decode.p25.message.tsbk.osp.control.ProtectionParameterUpdate;
import decode.p25.message.tsbk.osp.control.RFSSStatusBroadcast;
import decode.p25.message.tsbk.osp.control.RadioUnitMonitorCommand;
import decode.p25.message.tsbk.osp.control.RoamingAddressCommand;
import decode.p25.message.tsbk.osp.control.SecondaryControlChannelBroadcast;
import decode.p25.message.tsbk.osp.control.StatusQuery;
import decode.p25.message.tsbk.osp.control.StatusUpdate;
import decode.p25.message.tsbk.osp.control.SystemServiceBroadcast;
import decode.p25.message.tsbk.osp.control.UnitDeregistrationAcknowledge;
import decode.p25.message.tsbk.osp.control.UnitRegistrationCommand;
import decode.p25.message.tsbk.osp.control.UnitRegistrationResponse;
import decode.p25.message.tsbk.osp.data.GroupDataChannelAnnouncement;
import decode.p25.message.tsbk.osp.data.GroupDataChannelAnnouncementExplicit;
import decode.p25.message.tsbk.osp.data.GroupDataChannelGrant;
@@ -46,42 +57,6 @@ public class TSBKMessageFactory
case STANDARD:
switch( Opcode.fromValue( opcode ) )
{
case GROUP_VOICE_CHANNEL_GRANT:
return new GroupVoiceChannelGrant( message, duid,
aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
return new GroupVoiceChannelGrantUpdate( message, duid,
aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT:
return new GroupVoiceChannelGrantUpdateExplicit( message,
duid, aliasList );
case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT:
return new TelephoneInterconnectVoiceChannelGrant(
message, duid, aliasList );
case TELEPHONE_INTERCONNECT_ANSWER_REQUEST:
return new TelephoneInterconnectAnswerRequest(
message, duid, aliasList );
case UNIT_TO_UNIT_ANSWER_REQUEST:
return new UnitToUnitAnswerRequest( message, duid,
aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT:
return new UnitToUnitVoiceChannelGrant( message,
duid, aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE:
return new UnitToUnitVoiceChannelGrantUpdate( message,
duid, aliasList );
case INDIVIDUAL_DATA_CHANNEL_GRANT:
return new IndividualDataChannelGrant( message, duid,
aliasList );
case GROUP_DATA_CHANNEL_GRANT:
return new GroupDataChannelGrant( message, duid,
aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT:
return new GroupDataChannelAnnouncement( message, duid,
aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT:
return new GroupDataChannelAnnouncementExplicit(
message, duid, aliasList );
case ACKNOWLEDGE_RESPONSE_FNE:
return new AcknowledgeResponse( message, duid,
aliasList );
@@ -104,8 +79,32 @@ public class TSBKMessageFactory
case GROUP_AFFILIATION_RESPONSE:
return new GroupAffiliationResponse( message, duid,
aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT:
return new GroupDataChannelAnnouncement( message, duid,
aliasList );
case GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT:
return new GroupDataChannelAnnouncementExplicit(
message, duid, aliasList );
case GROUP_DATA_CHANNEL_GRANT:
return new GroupDataChannelGrant( message, duid,
aliasList );
case GROUP_VOICE_CHANNEL_GRANT:
return new GroupVoiceChannelGrant( message, duid,
aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE:
return new GroupVoiceChannelGrantUpdate( message, duid,
aliasList );
case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT:
return new GroupVoiceChannelGrantUpdateExplicit( message,
duid, aliasList );
case IDENTIFIER_UPDATE:
return new IdentifierUpdate( message, duid, aliasList );
case INDIVIDUAL_DATA_CHANNEL_GRANT:
return new IndividualDataChannelGrant( message, duid,
aliasList );
case LOCATION_REGISTRATION_RESPONSE:
return new LocationRegistrationResponse( message, duid,
aliasList );
case MESSAGE_UPDATE:
return new MessageUpdate( message, duid, aliasList );
case NETWORK_STATUS_BROADCAST:
@@ -114,6 +113,49 @@ public class TSBKMessageFactory
case PROTECTION_PARAMETER_UPDATE:
return new ProtectionParameterUpdate( message, duid,
aliasList );
case RADIO_UNIT_MONITOR_COMMAND:
return new RadioUnitMonitorCommand( message, duid,
aliasList );
case RFSS_STATUS_BROADCAST:
return new RFSSStatusBroadcast( message, duid,
aliasList );
case ROAMING_ADDRESS_COMMAND:
return new RoamingAddressCommand( message, duid,
aliasList );
case SECONDARY_CONTROL_CHANNEL_BROADCAST:
return new SecondaryControlChannelBroadcast( message,
duid, aliasList );
case STATUS_QUERY:
return new StatusQuery( message, duid, aliasList );
case STATUS_UPDATE:
return new StatusUpdate( message, duid, aliasList );
case SYSTEM_SERVICE_BROADCAST:
return new SystemServiceBroadcast( message, duid,
aliasList );
case TELEPHONE_INTERCONNECT_ANSWER_REQUEST:
return new TelephoneInterconnectAnswerRequest(
message, duid, aliasList );
case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT:
return new TelephoneInterconnectVoiceChannelGrant(
message, duid, aliasList );
case UNIT_DEREGISTRATION_ACKNOWLEDGE:
return new UnitDeregistrationAcknowledge( message,
duid, aliasList );
case UNIT_REGISTRATION_COMMAND:
return new UnitRegistrationCommand( message, duid,
aliasList );
case UNIT_REGISTRATION_RESPONSE:
return new UnitRegistrationResponse( message, duid,
aliasList );
case UNIT_TO_UNIT_ANSWER_REQUEST:
return new UnitToUnitAnswerRequest( message, duid,
aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT:
return new UnitToUnitVoiceChannelGrant( message,
duid, aliasList );
case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE:
return new UnitToUnitVoiceChannelGrantUpdate( message,
duid, aliasList );
default:
return new TSBKMessage( message, duid, aliasList );
}

View File

@@ -62,7 +62,7 @@ public class AdjacentStatusBroadcast extends TSBKMessage
sb.append( " FAILURE-CONDITION" );
}
if( isValid() )
if( isValidSiteInformation() )
{
sb.append( " VALID-INFO" );
}
@@ -126,31 +126,4 @@ public class AdjacentStatusBroadcast extends TSBKMessage
{
return mMessage.getInt( SYSTEM_SERVICE_CLASS );
}
public String getSourceAddress()
{
if( hasAdditionalInformation() && !hasExtendedAddress() )
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
return null;
}
@Override
public String getFromID()
{
return getSourceAddress();
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -5,13 +5,12 @@ import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Response;
public class GroupAffiliationResponse extends TSBKMessage
{
public enum AffiliationStatus { ACCEPT, FAIL, DENY, REFUSED };
public static final int LOCAL_GLOBAL_AFFILIATION_FLAG = 80;
public static final int[] GROUP_AFFILIATION_VALUE = { 86,87 };
public static final int[] AFFILIATION_RESPONSE = { 86,87 };
public static final int[] ANNOUNCEMENT_GROUP_ADDRESS = { 88,89,90,91,
92,93,94,95,96,97,98,99,100,101,102,103 };
public static final int[] GROUP_ADDRESS = { 104,105,106,107,108,109,110,111,
@@ -38,7 +37,7 @@ public class GroupAffiliationResponse extends TSBKMessage
sb.append( super.getMessage() );
sb.append( " STATUS:" + getStatus().name() );
sb.append( " AFFILIATION:" + getResponse().name() );
sb.append( " ANNOUNCE GROUP:" + getAnnouncementGroupAddress() );
sb.append( " GRP ADDR:" + getGroupAddress() );
sb.append( " TGT ADDR: " + getTargetAddress() );
@@ -51,11 +50,11 @@ public class GroupAffiliationResponse extends TSBKMessage
return mMessage.get( LOCAL_GLOBAL_AFFILIATION_FLAG) ? " GLOBAL" : " LOCAL";
}
public AffiliationStatus getStatus()
public Response getResponse()
{
int status = mMessage.getInt( GROUP_AFFILIATION_VALUE );
int response = mMessage.getInt( AFFILIATION_RESPONSE );
return AffiliationStatus.values()[ status ];
return Response.fromValue( response );
}
public String getAnnouncementGroupAddress()

View File

@@ -0,0 +1,78 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Response;
public class LocationRegistrationResponse extends TSBKMessage
{
public static final int[] REGISTRATION_RESPONSE = { 86,87 };
public static final int[] GROUP_ADDRESS = { 88,89,90,91,92,93,94,95,96,97,
98,99,100,101,102,103 };
public static final int[] RFSS_ID = { 104,105,106,107,108,109,110,111 };
public static final int[] SITE_ID = { 112,113,114,115,116,117,118,119 };
public static final int[] TARGET_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public LocationRegistrationResponse( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.LOCATION_REGISTRATION_RESPONSE.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " REGISTRATION:" + getResponse().name() );
sb.append( " GROUP:" + getGroupAddress() );
sb.append( " RFSS: " + getRFSSID() );
sb.append( " SITE: " + getSiteID() );
sb.append( " TGT ADDR: " + getTargetAddress() );
return sb.toString();
}
public Response getResponse()
{
return Response.fromValue( mMessage.getInt( REGISTRATION_RESPONSE ) );
}
public String getGroupAddress()
{
return mMessage.getHex( GROUP_ADDRESS, 6 );
}
public String getRFSSID()
{
return mMessage.getHex( RFSS_ID, 2 );
}
public String getSiteID()
{
return mMessage.getHex( SITE_ID, 2 );
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -0,0 +1,96 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class RFSSStatusBroadcast extends TSBKMessage
{
public static final int[] LOCATION_REGISTRATION_AREA = { 80,81,82,83,84,85,
86,87 };
public static final int ACTIVE_NETWORK_CONNECTION_FLAG = 91;
public static final int[] SYSTEM_ID = { 92,93,94,95,96,97,98,99,100,101,
102,103 };
public static final int[] RFSS_ID = { 104,105,106,107,108,109,110,111 };
public static final int[] SITE_ID = { 112,113,114,115,116,117,118,119 };
public static final int[] CHANNEL = { 120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135 };
public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141,
142,143 };
public RFSSStatusBroadcast( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.RFSS_STATUS_BROADCAST.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " LRA:" + getLocationRegistrationArea() );
sb.append( " SYSID:" + getSystemID() );
sb.append( " RFSS:" + getRFSS() );
sb.append( " SITE:" + getSiteID() );
sb.append( " CHAN:" + getChannel() );
if( hasActiveNetworkConnection() )
{
sb.append( " ACTIVE-NETWORK-CONN" );
}
sb.append( SystemService.toString( getSystemServiceClass() ) );
return sb.toString();
}
public String getLocationRegistrationArea()
{
return mMessage.getHex( LOCATION_REGISTRATION_AREA, 2 );
}
public boolean hasActiveNetworkConnection()
{
return mMessage.get( ACTIVE_NETWORK_CONNECTION_FLAG );
}
public String getSystemID()
{
return mMessage.getHex( SYSTEM_ID, 3 );
}
public String getRFSS()
{
return mMessage.getHex( RFSS_ID, 2 );
}
public String getSiteID()
{
return mMessage.getHex( SITE_ID, 2 );
}
public int getChannel()
{
return mMessage.getInt( CHANNEL );
}
public int getSystemServiceClass()
{
return mMessage.getInt( SYSTEM_SERVICE_CLASS );
}
}

View File

@@ -0,0 +1,69 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class RadioUnitMonitorCommand extends TSBKMessage
{
public static final int[] TX_MULTIPLIER = { 94,95 };
public static final int[] SOURCE_ADDRESS = { 96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 };
public static final int[] TARGET_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public RadioUnitMonitorCommand( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.RADIO_UNIT_MONITOR_COMMAND.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " MULT:" + getTransmitMultiplier() );
sb.append( " SRC ADDR: " + getSourceAddress() );
sb.append( " TGT ADDR: " + getTargetAddress() );
return sb.toString();
}
public int getTransmitMultiplier()
{
return mMessage.getInt( TX_MULTIPLIER );
}
public String getSourceAddress()
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
@Override
public String getFromID()
{
return getSourceAddress();
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -0,0 +1,73 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Response;
import decode.p25.reference.StackOperation;
public class RoamingAddressCommand extends TSBKMessage
{
public static final int[] STACK_OPERATION = { 80,81,82,83,84,85,86,87 };
public static final int[] WACN = { 88,89,90,91,92,93,94,95,96,97,98,99,100,
101,102,103,104,105,106,107 };
public static final int[] SYSTEM_ID = { 108,109,110,111,112,113,114,115,116,
117,118,119 };
public static final int[] TARGET_ID = { 120,121,122,123,124,125,126,127,128,
129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public RoamingAddressCommand( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.ROAMING_ADDRESS_COMMAND.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( getStackOperation().name() );
sb.append( " WACN:" + getWACN() );
sb.append( " SYSTEM: " + getSystemID() );
sb.append( " TGT ID: " + getTargetID() );
return sb.toString();
}
public StackOperation getStackOperation()
{
return StackOperation.fromValue( mMessage.getInt( STACK_OPERATION ) );
}
public String getWACN()
{
return mMessage.getHex( WACN, 5 );
}
public String getSystemID()
{
return mMessage.getHex( SYSTEM_ID, 3 );
}
public String getTargetID()
{
return mMessage.getHex( TARGET_ID, 6 );
}
@Override
public String getToID()
{
return getTargetID();
}
}

View File

@@ -0,0 +1,98 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class SecondaryControlChannelBroadcast extends TSBKMessage
{
public static final int[] RFSS_ID = { 80,81,82,83,84,85,86,87 };
public static final int[] SITE_ID = { 88,89,90,91,92,93,94,95 };
public static final int[] CHANNEL_1 = { 96,97,98,99,100,101,102,103,104,105,
106,107,108,109,110,111 };
public static final int[] SYSTEM_SERVICE_CLASS_1 = { 112,113,114,115,116,
117,118,119 };
public static final int[] CHANNEL_2 = { 120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135 };
public static final int[] SYSTEM_SERVICE_CLASS_2 = { 136,137,138,139,140,
141,142,143 };
public SecondaryControlChannelBroadcast( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.SECONDARY_CONTROL_CHANNEL_BROADCAST.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " RFSS:" + getRFSS() );
sb.append( " SITE:" + getSiteID() );
sb.append( " CHAN 1:" + getChannel1() );
sb.append( " SVC CLASS 1:" +
SystemService.toString( getSystemServiceClass1() ) );
if( hasChannel2() )
{
sb.append( " CHAN 2:" + getChannel2() );
sb.append( " SVC CLASS 2:" +
SystemService.toString( getSystemServiceClass2() ) );
}
else
{
sb.append( " CHAN 2: empty" );
}
return sb.toString();
}
public String getRFSS()
{
return mMessage.getHex( RFSS_ID, 2 );
}
public String getSiteID()
{
return mMessage.getHex( SITE_ID, 2 );
}
public int getChannel1()
{
return mMessage.getInt( CHANNEL_1 );
}
public int getSystemServiceClass1()
{
return mMessage.getInt( SYSTEM_SERVICE_CLASS_1 );
}
public int getChannel2()
{
return mMessage.getInt( CHANNEL_2 );
}
public int getSystemServiceClass2()
{
return mMessage.getInt( SYSTEM_SERVICE_CLASS_2 );
}
public boolean hasChannel2()
{
return getSystemServiceClass2() != 0;
}
}

View File

@@ -0,0 +1,62 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class StatusQuery extends TSBKMessage
{
public static final int[] TARGET_ADDRESS = { 96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 };
public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public StatusQuery( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.STATUS_QUERY.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " SRC ADDR: " + getSourceAddress() );
sb.append( " TGT ADDR: " + getTargetAddress() );
return sb.toString();
}
public String getSourceAddress()
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
@Override
public String getFromID()
{
return getSourceAddress();
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -0,0 +1,76 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class StatusUpdate extends TSBKMessage
{
public static final int[] USER_STATUS = { 80,81,82,83,84,85,86,87 };
public static final int[] UNIT_STATUS = { 88,89,90,91,92,93,94,95 };
public static final int[] TARGET_ADDRESS = { 96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 };
public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public StatusUpdate( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.STATUS_QUERY.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " STATUS USER:" + getUserStatus() );
sb.append( " UNIT:" + getUnitStatus() );
sb.append( " SRC ADDR: " + getSourceAddress() );
sb.append( " TGT ADDR: " + getTargetAddress() );
return sb.toString();
}
public String getUserStatus()
{
return mMessage.getHex( USER_STATUS, 2 );
}
public String getUnitStatus()
{
return mMessage.getHex( UNIT_STATUS, 2 );
}
public String getSourceAddress()
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
@Override
public String getFromID()
{
return getSourceAddress();
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -0,0 +1,64 @@
package decode.p25.message.tsbk.osp.control;
import java.util.List;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Service;
public class SystemServiceBroadcast extends TSBKMessage
{
public static final int[] AVAILABLE_SERVICES = { 88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111 };
public static final int[] SUPPORTED_SERVICES = { 112,113,114,115,116,117,
118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135 };
public static final int[] REQUEST_PRIORITY_LEVEL = { 136,137,138,139,140,
141,142,143 };
public SystemServiceBroadcast( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.SYSTEM_SERVICE_BROADCAST.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " SERVICES AVAILABLE " );
sb.append( getAvailableServices() );
sb.append( " SUPPORTED " );
sb.append( getSupportedServices() );
return sb.toString();
}
public List<Service> getAvailableServices()
{
long bitmap = mMessage.getLong( AVAILABLE_SERVICES );
return Service.getServices( bitmap );
}
public List<Service> getSupportedServices()
{
long bitmap = mMessage.getLong( SUPPORTED_SERVICES );
return Service.getServices( bitmap );
}
}

View File

@@ -0,0 +1,65 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Response;
public class UnitDeregistrationAcknowledge extends TSBKMessage
{
public static final int[] WACN = { 88,89,90,91,92,93,94,95,96,97,98,99,100,
101,102,103,104,105,106,107 };
public static final int[] SYSTEM_ID = { 108,109,110,111,112,113,114,115,
116,117,118,119 };
public static final int[] SOURCE_ID = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public UnitDeregistrationAcknowledge( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.UNIT_DEREGISTRATION_ACKNOWLEDGE.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " WACN:" + getWACN() );
sb.append( " SYSTEM:" + getSystemID() );
sb.append( " SRC ID: " + getSourceID() );
return sb.toString();
}
public String getWACN()
{
return mMessage.getHex( WACN, 5 );
}
public String getSystemID()
{
return mMessage.getHex( SYSTEM_ID, 3 );
}
public String getSourceID()
{
return mMessage.getHex( SOURCE_ID, 6 );
}
@Override
public String getToID()
{
return getSourceID();
}
}

View File

@@ -0,0 +1,62 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
public class UnitRegistrationCommand extends TSBKMessage
{
public static final int[] TARGET_ADDRESS = { 96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 };
public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public UnitRegistrationCommand( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.UNIT_REGISTRATION_COMMAND.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " SRC ADDR: " + getSourceAddress() );
sb.append( " TGT ADDR: " + getTargetAddress() );
return sb.toString();
}
public String getSourceAddress()
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
@Override
public String getFromID()
{
return getSourceAddress();
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getTargetAddress();
}
}

View File

@@ -0,0 +1,71 @@
package decode.p25.message.tsbk.osp.control;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.TSBKMessage;
import decode.p25.reference.DataUnitID;
import decode.p25.reference.Opcode;
import decode.p25.reference.Response;
public class UnitRegistrationResponse extends TSBKMessage
{
public static final int[] REGISTRATION_RESPONSE = { 82,83 };
public static final int[] SYSTEM_ID = { 84,85,86,87,88,89,90,91,92,93,94,95 };
public static final int[] SOURCE_ID = { 96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119 };
public static final int[] SOURCE_ADDRESS = { 120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143 };
public UnitRegistrationResponse( BitSetBuffer message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.UNIT_REGISTRATION_RESPONSE.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( super.getMessage() );
sb.append( " REGISTRATION:" + getResponse().name() );
sb.append( " SYSTEM:" + getSystemID() );
sb.append( " SRC ID: " + getSourceID() );
sb.append( " SRC ADDR: " + getSourceAddress() );
return sb.toString();
}
public Response getResponse()
{
return Response.fromValue( mMessage.getInt( REGISTRATION_RESPONSE ) );
}
public String getSystemID()
{
return mMessage.getHex( SYSTEM_ID, 3 );
}
public String getSourceID()
{
return mMessage.getHex( SOURCE_ID, 6 );
}
public String getSourceAddress()
{
return mMessage.getHex( SOURCE_ADDRESS, 6 );
}
@Override
public String getToID()
{
return getSourceAddress();
}
}

View File

@@ -0,0 +1,20 @@
package decode.p25.reference;
public enum Response
{
ACCEPT,
FAIL,
DENY,
REFUSED,
UNKNOWN;
public static Response fromValue( int value )
{
if( 0 <= value && value <= 4 )
{
return values()[ value ];
}
return UNKNOWN;
}
}

View File

@@ -0,0 +1,67 @@
package decode.p25.reference;
import java.util.ArrayList;
import java.util.List;
public enum Service
{
EXTENDED_SERVICES( 0x800000l ),
EXTENDED_SERVICES_EXTENSION( 0x400000l ),
/* NORMAL SERVICES */
NETWORK_ACTIVE( 0x200000l ),
RESERVED_4( 0x100000l ),
GROUP_VOICE( 0x080000l ),
INDIVIDUAL_VOICE( 0x040000l ),
PSTN_TO_UNIT_VOICE( 0x020000l ),
UNIT_TO_PSTN_VOICE( 0x010000l ),
RESERVED_9( 0x008000l ),
GROUP_DATA( 0x004000l ),
INDIVIDUAL_DATA( 0x002000l ),
RESERVED_12( 0x001000l ),
UNIT_REGISTRATION( 0x000800l ),
GROUP_AFFILIATION( 0x000400l ),
GROUP_AFFILIATION_QUERY( 0x000200l ),
AUTHENTICATION( 0x000100l ),
ENCRYPTION_SETTINGS( 0x000080l ),
USER_STATUS( 0x000040l ),
USER_MESSAGE( 0x000020l ),
UNIT_STATUS( 0x000010l ),
USER_STATUS_QUERY( 0x000008l ),
UNIT_STATUS_QUERY( 0x000004l ),
UNIT_PAGE( 0x000002l ),
EMERGENCY_ALARM( 0x000001l ),
UNKNOWN( 0x0l );
private long mCode;
private Service( long code )
{
mCode = code;
}
public long getCode()
{
return mCode;
}
public static boolean isSupported( Service service, long serviceBitmap )
{
return ( service.getCode() & serviceBitmap ) == service.getCode();
}
public static List<Service> getServices( long serviceBitmap )
{
List<Service> services = new ArrayList<Service>();
for( Service service: values() )
{
if( isSupported( service, serviceBitmap ) )
{
services.add( service );
}
}
return services;
}
}

View File

@@ -0,0 +1,20 @@
package decode.p25.reference;
public enum StackOperation
{
CLEAR,
WRITE,
DELETE,
READ,
UNKNOWN;
public static StackOperation fromValue( int value )
{
if( 0 <= value && value <= 3 )
{
return values()[ value ];
}
return UNKNOWN;
}
}