From fb630916a923093890d41708bd4494df6d10f62c Mon Sep 17 00:00:00 2001 From: "dennis.sheirer" Date: Sat, 6 Dec 2014 20:19:34 +0000 Subject: [PATCH] P25 work in progress --- src/decode/DecoderType.java | 30 +-- src/decode/p25/P25ActivitySummary.java | 4 +- src/decode/p25/P25ChannelState.java | 2 +- src/decode/p25/message/P25Message.java | 8 + .../p25/message/pdu/PDUMessageFactory.java | 74 ++++++ .../pdu/UnitToUnitChannelGrantExtended.java | 184 +++++++++++++ .../AdjacentStatusBroadcastExtended.java | 155 +++++++++++ .../pdu/osp/control/CallAlertExtended.java | 75 ++++++ .../GroupAffiliationQueryExtended.java | 75 ++++++ .../GroupAffiliationResponseExtended.java | 126 +++++++++ .../osp/control/MessageUpdateExtended.java | 85 ++++++ .../NetworkStatusBroadcastExtended.java | 3 +- .../control/ProtectionParameterBroadcast.java | 107 ++++++++ .../control}/RFSSStatusBroadcastExtended.java | 3 +- .../control/RoamingAddressUpdateExtended.java | 248 ++++++++++++++++++ .../pdu/osp/control/StatusQueryExtended.java | 75 ++++++ .../pdu/osp/control/StatusUpdateExtended.java | 91 +++++++ .../UnitRegistrationResponseExtended.java | 88 +++++++ .../data/GroupDataChannelGrantExtended.java | 163 ++++++++++++ .../IndividualDataChannelGrantExtended.java | 25 ++ .../voice/GroupVoiceChannelGrantExplicit.java | 161 ++++++++++++ ...phoneInterconnectChannelGrantExplicit.java | 168 ++++++++++++ ...nterconnectChannelGrantUpdateExplicit.java | 22 ++ .../UnitToUnitAnswerRequestExplicit.java | 105 ++++++++ .../UnitToUnitVoiceChannelGrantExtended.java | 25 ++ ...ToUnitVoiceChannelGrantUpdateExtended.java | 191 ++++++++++++++ .../p25/message/tsbk/ServiceMessage.java | 3 - .../p25/message/tsbk/TSBKMessageFactory.java | 2 +- .../tsbk/osp/control/AcknowledgeResponse.java | 2 +- .../osp/voice/GroupVoiceChannelGrant.java | 1 - src/decode/p25/reference/Opcode.java | 2 +- 31 files changed, 2276 insertions(+), 27 deletions(-) create mode 100644 src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/CallAlertExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/GroupAffiliationQueryExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/GroupAffiliationResponseExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/MessageUpdateExtended.java rename src/decode/p25/message/pdu/{ => osp/control}/NetworkStatusBroadcastExtended.java (97%) create mode 100644 src/decode/p25/message/pdu/osp/control/ProtectionParameterBroadcast.java rename src/decode/p25/message/pdu/{ => osp/control}/RFSSStatusBroadcastExtended.java (98%) create mode 100644 src/decode/p25/message/pdu/osp/control/RoamingAddressUpdateExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/StatusQueryExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/StatusUpdateExtended.java create mode 100644 src/decode/p25/message/pdu/osp/control/UnitRegistrationResponseExtended.java create mode 100644 src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java create mode 100644 src/decode/p25/message/pdu/osp/data/IndividualDataChannelGrantExtended.java create mode 100644 src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java create mode 100644 src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java create mode 100644 src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantUpdateExplicit.java create mode 100644 src/decode/p25/message/pdu/osp/voice/UnitToUnitAnswerRequestExplicit.java create mode 100644 src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantExtended.java create mode 100644 src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java diff --git a/src/decode/DecoderType.java b/src/decode/DecoderType.java index 8487051b..ffdd8196 100644 --- a/src/decode/DecoderType.java +++ b/src/decode/DecoderType.java @@ -25,28 +25,28 @@ import java.util.EnumSet; */ public enum DecoderType { - AM( "AM", "AM", "images/am", 10000 ), - FLEETSYNC2( "Fleetsync II", "Fsync2", "images/fm", 12500 ), - LJ_1200( "LJ1200 173.075", "LJ1200", "images/lj1200", 12500 ), - LTR_STANDARD( "LTR-Standard", "LTR", "images/ltr_standard", 10000 ), - LTR_NET( "LTR-Net", "LTR-Net", "images/ltr_net", 10000 ), - MDC1200( "MDC1200", "MDC1200", "images/fm", 12500 ), - MPT1327( "MPT1327", "MPT1327", "images/mpt1327", 12500 ), - NBFM( "NBFM", "NBFM", "images/fm", 12500 ), - PASSPORT( "Passport", "Passport", "images/passport", 12500 ), - P25_PHASE1( "P25 Phase 1", "P25-1", "images/p25p1", 12500 ); + AM( "AM", "AM", "images/am.png", 10000 ), + FLEETSYNC2( "Fleetsync II", "Fsync2", "images/fm.png", 12500 ), + LJ_1200( "LJ1200 173.075", "LJ1200", "images/lj1200.png", 12500 ), + LTR_STANDARD( "LTR-Standard", "LTR", "images/ltr_standard.png", 10000 ), + LTR_NET( "LTR-Net", "LTR-Net", "images/ltr_net.png", 10000 ), + MDC1200( "MDC1200", "MDC1200", "images/fm.png", 12500 ), + MPT1327( "MPT1327", "MPT1327", "images/mpt1327.png", 12500 ), + NBFM( "NBFM", "NBFM", "images/fm.png", 12500 ), + PASSPORT( "Passport", "Passport", "images/passport.png", 12500 ), + P25_PHASE1( "P25 Phase 1", "P25-1", "images/p25_1.png", 12500 ); private String mDisplayString; private String mShortDisplayString; - private String mIconPrefix; + private String mIconFilename; private int mChannelBandwidth; DecoderType( String displayString, String shortDisplayString, - String iconPrefix, int bandwidth ) + String iconFilename, int bandwidth ) { mDisplayString = displayString; mShortDisplayString = shortDisplayString; - mIconPrefix = iconPrefix; + mIconFilename = iconFilename; mChannelBandwidth = bandwidth; } @@ -102,9 +102,9 @@ public enum DecoderType return mShortDisplayString; } - public String getIconPrefix() + public String getIconFilename() { - return mIconPrefix; + return mIconFilename; } public int getChannelBandwidth() diff --git a/src/decode/p25/P25ActivitySummary.java b/src/decode/p25/P25ActivitySummary.java index 62e32f98..70a321ef 100644 --- a/src/decode/p25/P25ActivitySummary.java +++ b/src/decode/p25/P25ActivitySummary.java @@ -26,9 +26,9 @@ import sample.Listener; import alias.AliasList; import controller.activity.ActivitySummaryProvider; import decode.p25.message.P25Message; -import decode.p25.message.pdu.NetworkStatusBroadcastExtended; import decode.p25.message.pdu.PDUMessage; -import decode.p25.message.pdu.RFSSStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.NetworkStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.RFSSStatusBroadcastExtended; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.message.tsbk.osp.control.AdjacentStatusBroadcast; import decode.p25.message.tsbk.osp.control.NetworkStatusBroadcast; diff --git a/src/decode/p25/P25ChannelState.java b/src/decode/p25/P25ChannelState.java index 58ef629f..ddcfab0f 100644 --- a/src/decode/p25/P25ChannelState.java +++ b/src/decode/p25/P25ChannelState.java @@ -26,7 +26,7 @@ import controller.channel.ProcessingChain; import controller.state.AuxChannelState; import controller.state.ChannelState; import decode.p25.message.P25Message; -import decode.p25.message.pdu.RFSSStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.RFSSStatusBroadcastExtended; import decode.p25.message.tsbk.osp.control.RFSSStatusBroadcast; public class P25ChannelState extends ChannelState diff --git a/src/decode/p25/message/P25Message.java b/src/decode/p25/message/P25Message.java index 1aacbd2e..5956edcc 100644 --- a/src/decode/p25/message/P25Message.java +++ b/src/decode/p25/message/P25Message.java @@ -1,5 +1,7 @@ package decode.p25.message; +import java.text.SimpleDateFormat; + import map.Plottable; import message.Message; import alias.Alias; @@ -10,12 +12,18 @@ import decode.p25.reference.DataUnitID; public class P25Message extends Message { + public enum DuplexMode { HALF, FULL }; + public enum SessionMode { PACKET, CIRCUIT }; + public static final int[] NAC = { 0,1,2,3,4,5,6,7,8,9,10,11 }; public static final int[] DUID = { 12,13,14,15 }; public static final int[] BCH = { 16,17,18,19,20,21,22,23,24,25,26,27,28,29, 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, 54,55,56,57,58,59,60,61,62,63 }; + protected SimpleDateFormat mTimeDurationFormat = + new SimpleDateFormat( "HH:mm:ss.SSS"); + protected BitSetBuffer mMessage; protected DataUnitID mDUID; protected AliasList mAliasList; diff --git a/src/decode/p25/message/pdu/PDUMessageFactory.java b/src/decode/p25/message/pdu/PDUMessageFactory.java index 99c81343..72e95ea7 100644 --- a/src/decode/p25/message/pdu/PDUMessageFactory.java +++ b/src/decode/p25/message/pdu/PDUMessageFactory.java @@ -2,6 +2,26 @@ package decode.p25.message.pdu; import alias.AliasList; import bits.BitSetBuffer; +import decode.p25.message.pdu.osp.control.AdjacentStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.CallAlertExtended; +import decode.p25.message.pdu.osp.control.GroupAffiliationQueryExtended; +import decode.p25.message.pdu.osp.control.GroupAffiliationResponseExtended; +import decode.p25.message.pdu.osp.control.MessageUpdateExtended; +import decode.p25.message.pdu.osp.control.NetworkStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.ProtectionParameterBroadcast; +import decode.p25.message.pdu.osp.control.RFSSStatusBroadcastExtended; +import decode.p25.message.pdu.osp.control.RoamingAddressUpdateExtended; +import decode.p25.message.pdu.osp.control.StatusQueryExtended; +import decode.p25.message.pdu.osp.control.StatusUpdateExtended; +import decode.p25.message.pdu.osp.control.UnitRegistrationResponseExtended; +import decode.p25.message.pdu.osp.data.GroupDataChannelGrantExtended; +import decode.p25.message.pdu.osp.data.IndividualDataChannelGrantExtended; +import decode.p25.message.pdu.osp.voice.GroupVoiceChannelGrantExplicit; +import decode.p25.message.pdu.osp.voice.TelephoneInterconnectChannelGrantExplicit; +import decode.p25.message.pdu.osp.voice.TelephoneInterconnectChannelGrantUpdateExplicit; +import decode.p25.message.pdu.osp.voice.UnitToUnitAnswerRequestExplicit; +import decode.p25.message.pdu.osp.voice.UnitToUnitVoiceChannelGrantExtended; +import decode.p25.message.pdu.osp.voice.UnitToUnitVoiceChannelGrantUpdateExtended; import decode.p25.reference.DataUnitID; import decode.p25.reference.Opcode; import decode.p25.reference.PDUFormat; @@ -30,12 +50,66 @@ public class PDUMessageFactory switch( opcode ) { + case ADJACENT_STATUS_BROADCAST: + return new AdjacentStatusBroadcastExtended( + message, duid, aliasList ); + case CALL_ALERT: + return new CallAlertExtended( message, duid, + aliasList ); + case GROUP_AFFILIATION_QUERY: + return new GroupAffiliationQueryExtended( + message, duid, aliasList ); + case GROUP_AFFILIATION_RESPONSE: + return new GroupAffiliationResponseExtended( + message, duid, aliasList ); + case GROUP_DATA_CHANNEL_GRANT: + return new GroupDataChannelGrantExtended( + message, duid, aliasList ); + case GROUP_VOICE_CHANNEL_GRANT: + return new GroupVoiceChannelGrantExplicit( + message, duid, aliasList ); + case INDIVIDUAL_DATA_CHANNEL_GRANT: + return new IndividualDataChannelGrantExtended( + message, duid, aliasList ); + case MESSAGE_UPDATE: + return new MessageUpdateExtended( message, duid, + aliasList ); case NETWORK_STATUS_BROADCAST: return new NetworkStatusBroadcastExtended( message, duid, aliasList ); + case PROTECTION_PARAMETER_BROADCAST: + return new ProtectionParameterBroadcast( + message, duid, aliasList ); case RFSS_STATUS_BROADCAST: return new RFSSStatusBroadcastExtended( message, duid, aliasList ); + case ROAMING_ADDRESS_UPDATE: + return new RoamingAddressUpdateExtended( + message, duid, aliasList ); + case STATUS_QUERY: + return new StatusQueryExtended( message, duid, + aliasList ); + case STATUS_UPDATE: + return new StatusUpdateExtended( message, duid, + aliasList ); + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: + return new TelephoneInterconnectChannelGrantExplicit( + message, duid, aliasList ); + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: + return new TelephoneInterconnectChannelGrantUpdateExplicit( + message, duid, aliasList ); + case UNIT_REGISTRATION_RESPONSE: + return new UnitRegistrationResponseExtended( + message, duid, aliasList ); + case UNIT_TO_UNIT_ANSWER_REQUEST: + return new UnitToUnitAnswerRequestExplicit( + message, duid, aliasList ); + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: + return new UnitToUnitVoiceChannelGrantExtended( + message, duid, aliasList ); + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: + return new UnitToUnitVoiceChannelGrantUpdateExtended( + message, duid, aliasList ); default: break; } diff --git a/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java b/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java new file mode 100644 index 00000000..a8f4bdcd --- /dev/null +++ b/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java @@ -0,0 +1,184 @@ +package decode.p25.message.pdu; + +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; +import decode.p25.reference.Opcode; + +public abstract class UnitToUnitChannelGrantExtended extends PDUMessage + implements IdentifierUpdateReceiver +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] SOURCE_ADDRESS = { 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[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] SOURCE_WACN = { 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175,176,177,178,179 }; + public static final int[] SOURCE_SYSTEM_ID = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] SOURCE_ID = { 192,193,194,195,196,197,198,199,200, + 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215 }; + public static final int[] TARGET_ADDRESS = { 216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 }; + public static final int[] TRANSMIT_IDENTIFIER = { 240,241,242,243 }; + public static final int[] TRANSMIT_CHANNEL = { 244,245,246,247,248,249,250, + 251,252,253,254,255 }; + public static final int[] RECEIVE_IDENTIFIER = { 256,257,258,259 }; + public static final int[] RECEIVE_CHANNEL = { 260,261,262,263,264,265,266, + 267,268,269,270,271 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, + 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, + 343,344,345,346,347,348,349,350,351 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public UnitToUnitChannelGrantExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " FROM ADDR:" ); + sb.append( getSourceAddress() ); + + sb.append( " ID:" ); + sb.append( getSourceID() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + sb.append( " CHAN DN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append( " " + getDownlinkFrequency() ); + + sb.append( " CHAN UP:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append( " " + getUplinkFrequency() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getSourceAddress() + { + return mMessage.getHex( SOURCE_ADDRESS, 6 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java new file mode 100644 index 00000000..b4d45921 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java @@ -0,0 +1,155 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.tsbk.osp.control.IdentifierUpdate; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.message.tsbk.osp.control.SystemService; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class AdjacentStatusBroadcastExtended extends PDUMessage + implements IdentifierUpdateReceiver +{ + public static final int[] LRA = { 88,89,90,91,92,93,94,95 }; + public static final int[] SYSTEM_ID = { 100,101,102,103,104,105,106,107,108, + 109,110,111 }; + public static final int[] RF_SUBSYSTEM_ID = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] SITE_ID = { 136,137,138,139,140,141,142,143 }; + public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; + public static final int[] TRANSMIT_CHANNEL = { 164,165,166,167,168,169,170, + 171,172,173,174,175 }; + public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; + public static final int[] RECEIVE_CHANNEL = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] SYSTEM_SERVICE_CLASS = { 192,193,194,195,196,197, + 198,199 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public AdjacentStatusBroadcastExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.ADJACENT_STATUS_BROADCAST.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " LRA:" + getLocationRegistrationArea() ); + + sb.append( " SYS:" + getSystemID() ); + + sb.append( " RFSS:" + getRFSubsystemID() ); + + sb.append( " SITE:" + getSiteID() ); + + sb.append( " CTRL CHAN:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + + sb.append( " DN:" + getDownlinkFrequency() ); + + sb.append( " " + getTransmitIdentifier() + "-" + getTransmitChannel() ); + + sb.append( " UP:" + getUplinkFrequency() ); + + sb.append( " SYS SVC CLASS:" + + SystemService.toString( getSystemServiceClass() ) ); + + return sb.toString(); + } + + + public String getLocationRegistrationArea() + { + return mMessage.getHex( LRA, 2 ); + } + + public String getSystemID() + { + return mMessage.getHex( SYSTEM_ID, 3 ); + } + + public String getRFSubsystemID() + { + return mMessage.getHex( RF_SUBSYSTEM_ID, 2 ); + } + + public String getSiteID() + { + return mMessage.getHex( SITE_ID, 2 ); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public int getSystemServiceClass() + { + return mMessage.getInt( SYSTEM_SERVICE_CLASS ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/pdu/osp/control/CallAlertExtended.java b/src/decode/p25/message/pdu/osp/control/CallAlertExtended.java new file mode 100644 index 00000000..cdcdc1c5 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/CallAlertExtended.java @@ -0,0 +1,75 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class CallAlertExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] WACN = { 128,129,130,131,132,133,134,135,136,137, + 138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SYSTEM_ID = { 164,165,166,167,168,169,170,171,172, + 173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public CallAlertExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.CALL_ALERT.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN:" ); + sb.append( getWACN() ); + + sb.append( " SYS:" ); + sb.append( getSystemID() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + 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 ); + } +} diff --git a/src/decode/p25/message/pdu/osp/control/GroupAffiliationQueryExtended.java b/src/decode/p25/message/pdu/osp/control/GroupAffiliationQueryExtended.java new file mode 100644 index 00000000..bd132ea8 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/GroupAffiliationQueryExtended.java @@ -0,0 +1,75 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class GroupAffiliationQueryExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] WACN = { 128,129,130,131,132,133,134,135,136,137, + 138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SYSTEM_ID = { 164,165,166,167,168,169,170,171,172, + 173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public GroupAffiliationQueryExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.GROUP_AFFILIATION_QUERY.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN:" ); + sb.append( getWACN() ); + + sb.append( " SYS:" ); + sb.append( getSystemID() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + 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 ); + } +} diff --git a/src/decode/p25/message/pdu/osp/control/GroupAffiliationResponseExtended.java b/src/decode/p25/message/pdu/osp/control/GroupAffiliationResponseExtended.java new file mode 100644 index 00000000..30d6ff77 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/GroupAffiliationResponseExtended.java @@ -0,0 +1,126 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; +import decode.p25.reference.Response; + +public class GroupAffiliationResponseExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] SOURCE_WACN = { 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SOURCE_SYSTEM_ID = { 164,165,166,167,168,169,170, + 171,172,173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] GROUP_WACN = { 200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215,216,217,218,219 }; + public static final int[] GROUP_SYSTEM_ID = { 220,221,222,223,224,225,226, + 227,228,229,230,231 }; + public static final int[] GROUP_ID = { 232,233,234,235,236,237,238,239,240, + 241,242,243,244,245,246,247 }; + public static final int[] ANNOUNCEMENT_GROUP_ID = { 248,249,250,251,252,253, + 254,255,256,257,258,259,260,261,262,263 }; + public static final int[] GROUP_AFFILIATION_RESPONSE_VALUE = { 270,271 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, + 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, + 343,344,345,346,347,348,349,350,351 }; + + public GroupAffiliationResponseExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.GROUP_AFFILIATION_RESPONSE.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( "AFFILIATION:" ); + sb.append( getGroupAffiliationResponse().name() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + sb.append( " GROUP:" ); + sb.append( getGroupID() ); + + sb.append( " WACN:" ); + sb.append( getGroupWACN() ); + + sb.append( " SYS:" ); + sb.append( getGroupSystemID() ); + + sb.append( " ANNOUNCEMENT GROUP:" ); + sb.append( getAnnouncementGroupID() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } + + public String getGroupWACN() + { + return mMessage.getHex( GROUP_WACN, 5 ); + } + + public String getGroupSystemID() + { + return mMessage.getHex( GROUP_SYSTEM_ID, 3 ); + } + + public String getGroupID() + { + return mMessage.getHex( GROUP_ID, 4 ); + } + + public String getAnnouncementGroupID() + { + return mMessage.getHex( GROUP_ID, 4 ); + } + + public Response getGroupAffiliationResponse() + { + return Response.fromValue( + mMessage.getInt( GROUP_AFFILIATION_RESPONSE_VALUE ) ); + } +} diff --git a/src/decode/p25/message/pdu/osp/control/MessageUpdateExtended.java b/src/decode/p25/message/pdu/osp/control/MessageUpdateExtended.java new file mode 100644 index 00000000..407571e8 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/MessageUpdateExtended.java @@ -0,0 +1,85 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class MessageUpdateExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] SOURCE_WACN = { 128,129,130,131,132,133,134,135,136,137, + 138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SOURCE_SYSTEM_ID = { 164,165,166,167,168,169,170,171,172, + 173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] SHORT_DATA_MESSAGE = { 200,201,202,203,204,205, + 206,207,208,209,210,211,212,213,214,215 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public MessageUpdateExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.CALL_ALERT.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " MSG:" ); + sb.append( getShortDataMessage() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } + + public String getShortDataMessage() + { + return mMessage.getHex( SHORT_DATA_MESSAGE, 4 ); + } +} diff --git a/src/decode/p25/message/pdu/NetworkStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java similarity index 97% rename from src/decode/p25/message/pdu/NetworkStatusBroadcastExtended.java rename to src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java index e92dc61b..b46832f3 100644 --- a/src/decode/p25/message/pdu/NetworkStatusBroadcastExtended.java +++ b/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java @@ -1,7 +1,8 @@ -package decode.p25.message.pdu; +package decode.p25.message.pdu.osp.control; import alias.AliasList; import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; import decode.p25.message.tsbk.osp.control.IdentifierUpdate; import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; import decode.p25.message.tsbk.osp.control.SystemService; diff --git a/src/decode/p25/message/pdu/osp/control/ProtectionParameterBroadcast.java b/src/decode/p25/message/pdu/osp/control/ProtectionParameterBroadcast.java new file mode 100644 index 00000000..bdb6f149 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/ProtectionParameterBroadcast.java @@ -0,0 +1,107 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Encryption; +import decode.p25.reference.Opcode; + +public class ProtectionParameterBroadcast extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] ENCRYPTION_TYPE = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] ALGORITHM_ID = { 136,137,138,139,140,141,142,143 }; + public static final int[] KEY_ID = { 160,161,162,163,164,165,166,167,168, + 169,170,171,172,173,174,175 }; + public static final int[] INBOUND_INITIALIZATION_VECTOR_A = { 176,177,178, + 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196, + 197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214, + 215 }; + public static final int[] INBOUND_INITIALIZATION_VECTOR_B = { 216,217,218, + 219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236, + 237,238,239,240,241,242,243,244,245,246,247 }; + public static final int[] OUTBOUND_INITIALIZATION_VECTOR_A = { 248,249,250, + 251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268, + 269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286, + 287 }; + public static final int[] OUTBOUND_INITIALIZATION_VECTOR_B = { 288,289,290, + 291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308, + 309,310,311,312,313,314,315,316,317,318,319 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, + 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, + 343,344,345,346,347,348,349,350,351 }; + + public ProtectionParameterBroadcast( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.PROTECTION_PARAMETER_BROADCAST.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " ENCRYPTION:" ); + sb.append( getEncryptionType().name() ); + + sb.append( " ALGORITHM ID:" ); + sb.append( getAlgorithmID() ); + + sb.append( " KEY ID:" ); + sb.append( getKeyID() ); + + sb.append( " INBOUND IV:" ); + sb.append( getInboundInitializationVector() ); + + sb.append( " OUTBOUND IV:" ); + sb.append( getOutboundInitializationVector() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public Encryption getEncryptionType() + { + return Encryption.fromValue( mMessage.getInt( ENCRYPTION_TYPE ) ); + } + + public String getAlgorithmID() + { + return mMessage.getHex( ALGORITHM_ID, 2 ); + } + + public String getKeyID() + { + return mMessage.getHex( KEY_ID, 4 ); + } + + public String getInboundInitializationVector() + { + return mMessage.getHex( INBOUND_INITIALIZATION_VECTOR_A, 10 ) + + mMessage.getHex( INBOUND_INITIALIZATION_VECTOR_B, 8 ); + } + + public String getOutboundInitializationVector() + { + return mMessage.getHex( OUTBOUND_INITIALIZATION_VECTOR_A, 10 ) + + mMessage.getHex( OUTBOUND_INITIALIZATION_VECTOR_B, 8 ); + } +} diff --git a/src/decode/p25/message/pdu/RFSSStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java similarity index 98% rename from src/decode/p25/message/pdu/RFSSStatusBroadcastExtended.java rename to src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java index db48177c..ab14edf9 100644 --- a/src/decode/p25/message/pdu/RFSSStatusBroadcastExtended.java +++ b/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java @@ -1,7 +1,8 @@ -package decode.p25.message.pdu; +package decode.p25.message.pdu.osp.control; import alias.AliasList; import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; import decode.p25.message.tsbk.osp.control.IdentifierUpdate; import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; import decode.p25.message.tsbk.osp.control.SystemService; diff --git a/src/decode/p25/message/pdu/osp/control/RoamingAddressUpdateExtended.java b/src/decode/p25/message/pdu/osp/control/RoamingAddressUpdateExtended.java new file mode 100644 index 00000000..cdb69c37 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/RoamingAddressUpdateExtended.java @@ -0,0 +1,248 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; +import dsp.fsk.P25MessageFramer; + +public class RoamingAddressUpdateExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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 LAST_MESSAGE_INDICATOR = 128; + public static final int[] MESSAGE_SEQUENCE_NUMBER = { 132,133,134,135 }; + public static final int[] WACN_A = { 136,137,138,139,140,141,142,143,160, + 161,162,163,164,165,166,167,168,169,170,171 }; + public static final int[] SYSTEM_ID_A = { 172,173,174,175,176,177,178,179, + 180,181,182,183 }; + public static final int[] SOURCE_ID_FORMAT_1 = { 184,185,186,187,188,189, + 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207 }; + public static final int[] WACN_B = { 184,185,186,187,188,189,190,191,192, + 193,194,195,196,197,198,199,200,201,202,203 }; + public static final int[] SYSTEM_ID_B = { 204,205,206,207,208,209,210,211, + 212,213,214,215 }; + public static final int[] WACN_C = { 216,217,218,219,220,221,222,223,224, + 225,226,227,228,229,230,231,232,233,234,235 }; + public static final int[] SYSTEM_ID_C = { 236,237,238,239,240,241,242,243, + 244,245,246,247 }; + public static final int[] WACN_D = { 248,249,250,251,252,253,254,255,256, + 257,258,259,260,261,262,263,264,265,266,267 }; + public static final int[] SYSTEM_ID_D = { 268,269,270,271,272,273,274,275, + 276,277,278,279 }; + public static final int[] SOURCE_ID_FORMAT_2 = { 280,281,282,283,284,285, + 286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303 }; + public static final int[] WACN_E = { 280,281,282,283,284,285, + 286,287,288,289,290,291,292,293,294,295,296,297,298,299 }; + public static final int[] SYSTEM_ID_E = { 300,301,302,303,304,305,306,307, + 308,309,310,311 }; + public static final int[] WACN_F = { 312,313,314,315,316,317,318,319,320, + 321,322,323,324,325,326,327,328,329,330,331 }; + public static final int[] SYSTEM_ID_F = { 332,333,334,335,336,337,338,339, + 340,341,342,343 }; + public static final int[] WACN_G = { 344,345,346,347,348,349,350,351,352, + 353,354,355,356,357,358,359,360,361,362,363 }; + public static final int[] SYSTEM_ID_G = { 364,365,366,367,368,369,370,371, + 372,373,374,375 }; + public static final int[] SOURCE_ID_FORMAT_3 = { 376,377,378,379,380,381, + 382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399 }; + public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_1 = { 224,225,226,227, + 228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245, + 246,247,248,249,250,251,252,253,254,255 }; + public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_2 = { 320,321,322,323, + 324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341, + 342,343,344,345,346,347,348,349,350,351 }; + public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_3 = { 416,417,418,419, + 420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437, + 438,439,440,441,442,443,444,445,446,447 }; + + private enum Format{ FORMAT_1, FORMAT_2, FORMAT_3 }; + + private Format mFormat; + + public RoamingAddressUpdateExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + + if( mMessage.size() == P25MessageFramer.PDU2_BEGIN ) + { + mFormat = Format.FORMAT_1; + } + else if( mMessage.size() == P25MessageFramer.PDU3_BEGIN ) + { + mFormat = Format.FORMAT_2; + } + else if( mMessage.size() == P25MessageFramer.PDU3_DECODED_END ) + { + mFormat = Format.FORMAT_3; + } + else + { + mFormat = Format.FORMAT_1; + } + } + + @Override + public String getEventType() + { + return Opcode.ROAMING_ADDRESS_UPDATE.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " ROAMING ADDRESS STACK FROM:" ); + sb.append( getSourceID() ); + + if( isLastBlock() ) + { + sb.append( " LAST BLOCK" ); + } + + sb.append( "MSG SEQ:" ); + sb.append( getMessageSequenceNumber() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN A:" + getWACNA() ); + sb.append( " SYS A:" + getSystemIDA() ); + + if( isFormat2() ) + { + sb.append( " WACN B:" + getWACNB() ); + sb.append( " SYS B:" + getSystemIDB() ); + sb.append( " WACN C:" + getWACNC() ); + sb.append( " SYS C:" + getSystemIDC() ); + sb.append( " WACN D:" + getWACND() ); + sb.append( " SYS D:" + getSystemIDD() ); + } + + if( isFormat3() ) + { + sb.append( " WACN E:" + getWACNE() ); + sb.append( " SYS E:" + getSystemIDE() ); + sb.append( " WACN F:" + getWACNF() ); + sb.append( " SYS F:" + getSystemIDF() ); + sb.append( " WACN G:" + getWACNG() ); + sb.append( " SYS G:" + getSystemIDG() ); + } + + return sb.toString(); + } + + public boolean isLastBlock() + { + return mMessage.get( LAST_MESSAGE_INDICATOR ); + } + + public int getMessageSequenceNumber() + { + return mMessage.getInt( MESSAGE_SEQUENCE_NUMBER ); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public String getWACNA() + { + return mMessage.getHex( WACN_A, 5 ); + } + + public String getSystemIDA() + { + return mMessage.getHex( SYSTEM_ID_A, 3 ); + } + + public String getWACNB() + { + return isFormat2() ? mMessage.getHex( WACN_B, 5 ) : null; + } + + public String getSystemIDB() + { + return isFormat2() ? mMessage.getHex( SYSTEM_ID_B, 3 ) : null; + } + + public String getWACNC() + { + return isFormat2() ? mMessage.getHex( WACN_C, 5 ) : null; + } + + public String getSystemIDC() + { + return isFormat2() ? mMessage.getHex( SYSTEM_ID_C, 3 ) : null; + } + + public String getWACND() + { + return isFormat2() ? mMessage.getHex( WACN_D, 5 ) : null; + } + + public String getSystemIDD() + { + return isFormat2() ? mMessage.getHex( SYSTEM_ID_D, 3 ) : null; + } + + public String getWACNE() + { + return isFormat3() ? mMessage.getHex( WACN_E, 5 ) : null; + } + + public String getSystemIDE() + { + return isFormat3() ? mMessage.getHex( SYSTEM_ID_E, 3 ) : null; + } + + public String getWACNF() + { + return isFormat3() ? mMessage.getHex( WACN_F, 5 ) : null; + } + + public String getSystemIDF() + { + return isFormat3() ? mMessage.getHex( SYSTEM_ID_F, 3 ) : null; + } + + public String getWACNG() + { + return isFormat3() ? mMessage.getHex( WACN_G, 5 ) : null; + } + + public String getSystemIDG() + { + return isFormat3() ? mMessage.getHex( SYSTEM_ID_G, 3 ) : null; + } + + public String getSourceID() + { + switch( mFormat ) + { + case FORMAT_1: + return mMessage.getHex( SOURCE_ID_FORMAT_1, 6 ); + case FORMAT_2: + return mMessage.getHex( SOURCE_ID_FORMAT_2, 6 ); + case FORMAT_3: + return mMessage.getHex( SOURCE_ID_FORMAT_2, 6 ); + } + + return null; + } + + public boolean isFormat2() + { + return mFormat != Format.FORMAT_3; + } + + public boolean isFormat3() + { + return mFormat == Format.FORMAT_3; + } +} diff --git a/src/decode/p25/message/pdu/osp/control/StatusQueryExtended.java b/src/decode/p25/message/pdu/osp/control/StatusQueryExtended.java new file mode 100644 index 00000000..cf7878fe --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/StatusQueryExtended.java @@ -0,0 +1,75 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class StatusQueryExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] SOURCE_WACN = { 128,129,130,131,132,133,134,135,136,137, + 138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SOURCE_SYSTEM_ID = { 164,165,166,167,168,169,170,171,172, + 173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public StatusQueryExtended( 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( getMessageStub() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } +} diff --git a/src/decode/p25/message/pdu/osp/control/StatusUpdateExtended.java b/src/decode/p25/message/pdu/osp/control/StatusUpdateExtended.java new file mode 100644 index 00000000..9a12b47a --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/StatusUpdateExtended.java @@ -0,0 +1,91 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class StatusUpdateExtended extends PDUMessage +{ + public static final int[] TARGET_ADDRESS = { 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[] SOURCE_WACN = { 128,129,130,131,132,133,134,135,136,137, + 138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SOURCE_SYSTEM_ID = { 164,165,166,167,168,169,170,171,172, + 173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] UNIT_STATUS = { 200,201,202,203,204,205,206,207 }; + public static final int[] USER_STATUS = { 208,209,210,211,212,213,214,215 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public StatusUpdateExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.STATUS_UPDATE.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + sb.append( " STATUS USER:" + getUserStatus() ); + sb.append( " UNIT:" + getUnitStatus() ); + + return sb.toString(); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } + + public String getUserStatus() + { + return mMessage.getHex( USER_STATUS, 2 ); + } + + public String getUnitStatus() + { + return mMessage.getHex( UNIT_STATUS, 2 ); + } + +} diff --git a/src/decode/p25/message/pdu/osp/control/UnitRegistrationResponseExtended.java b/src/decode/p25/message/pdu/osp/control/UnitRegistrationResponseExtended.java new file mode 100644 index 00000000..3a2a9544 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/control/UnitRegistrationResponseExtended.java @@ -0,0 +1,88 @@ +package decode.p25.message.pdu.osp.control; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; +import decode.p25.reference.Response; + +public class UnitRegistrationResponseExtended extends PDUMessage +{ + public static final int[] REGISTRATION_DEFAULT_ADDRESS = { 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[] WACN = { 128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143,160,161,162,163 }; + public static final int[] SYSTEM_ID = { 164,165,166,167,168,169,170, + 171,172,173,174,175 }; + public static final int[] SOURCE_ID = { 176,177,178,179,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199 }; + public static final int[] SOURCE_ADDRESS = { 200,201,202,203,204,205,206, + 207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223 }; + public static final int[] UNIT_REGISTRATION_RESPONSE_VALUE = { 230,231 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, + 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, + 343,344,345,346,347,348,349,350,351 }; + + public UnitRegistrationResponseExtended( 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( getMessageStub() ); + + sb.append( "REGISTRATION:" ); + sb.append( getUnitRegistrationResponse().name() ); + + sb.append( " SRC ID:" ); + sb.append( getSourceID() ); + + sb.append( " ADDR:" ); + sb.append( getSourceAddress() ); + + sb.append( " WACN:" ); + sb.append( getWACN() ); + + sb.append( " SYS:" ); + sb.append( getSystemID() ); + + 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 ); + } + + public String getSourceAddress() + { + return mMessage.getHex( SOURCE_ADDRESS, 6 ); + } + + public Response getUnitRegistrationResponse() + { + return Response.fromValue( + mMessage.getInt( UNIT_REGISTRATION_RESPONSE_VALUE ) ); + } +} diff --git a/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java b/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java new file mode 100644 index 00000000..9a5392e8 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java @@ -0,0 +1,163 @@ +package decode.p25.message.pdu.osp.data; + +import java.util.Date; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.tsbk.osp.control.IdentifierUpdate; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class GroupDataChannelGrantExtended extends PDUMessage + implements IdentifierUpdateReceiver +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] SOURCE_ADDRESS = { 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[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; + public static final int[] TRANSMIT_CHANNEL = { 164,165,166,167,168,169,170, + 171,172,173,174,175 }; + public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; + public static final int[] RECEIVE_CHANNEL = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] GROUP_ADDRESS = { 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public GroupDataChannelGrantExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " FROM:" ); + sb.append( getSourceAddress() ); + + sb.append( " TO:" ); + sb.append( getGroupAddress() ); + + sb.append( " CHAN DN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append( " " + getDownlinkFrequency() ); + + sb.append( " CHAN UP:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append( " " + getUplinkFrequency() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getSourceAddress() + { + return mMessage.getHex( SOURCE_ADDRESS, 6 ); + } + + public String getGroupAddress() + { + return mMessage.getHex( GROUP_ADDRESS, 4 ); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/pdu/osp/data/IndividualDataChannelGrantExtended.java b/src/decode/p25/message/pdu/osp/data/IndividualDataChannelGrantExtended.java new file mode 100644 index 00000000..31e2d366 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/data/IndividualDataChannelGrantExtended.java @@ -0,0 +1,25 @@ +package decode.p25.message.pdu.osp.data; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.UnitToUnitChannelGrantExtended; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class IndividualDataChannelGrantExtended + extends UnitToUnitChannelGrantExtended + implements IdentifierUpdateReceiver +{ + public IndividualDataChannelGrantExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.INDIVIDUAL_DATA_CHANNEL_GRANT.getDescription(); + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java b/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java new file mode 100644 index 00000000..3d1180e4 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java @@ -0,0 +1,161 @@ +package decode.p25.message.pdu.osp.voice; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.tsbk.osp.control.IdentifierUpdate; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class GroupVoiceChannelGrantExplicit extends PDUMessage + implements IdentifierUpdateReceiver +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] SOURCE_ADDRESS = { 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[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] TRANSMIT_IDENTIFIER = { 176,177,178,179 }; + public static final int[] TRANSMIT_CHANNEL = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] RECEIVE_IDENTIFIER = { 192,193,194,195 }; + public static final int[] RECEIVE_CHANNEL = { 196,197,198,199,200,201,202, + 203,204,205,206,207 }; + public static final int[] GROUP_ADDRESS = { 208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public GroupVoiceChannelGrantExplicit( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.GROUP_VOICE_CHANNEL_GRANT.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " FROM:" ); + sb.append( getSourceAddress() ); + + sb.append( " GRP:" ); + sb.append( getGroupAddress() ); + + sb.append( " CHAN DN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append( " " + getDownlinkFrequency() ); + + sb.append( " CHAN UP:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append( " " + getUplinkFrequency() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getSourceAddress() + { + return mMessage.getHex( SOURCE_ADDRESS, 6 ); + } + + public String getGroupAddress() + { + return mMessage.getHex( GROUP_ADDRESS, 4 ); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java new file mode 100644 index 00000000..36dc944d --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java @@ -0,0 +1,168 @@ +package decode.p25.message.pdu.osp.voice; + +import java.util.Date; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.tsbk.osp.control.IdentifierUpdate; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage + implements IdentifierUpdateReceiver +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] ADDRESS = { 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[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] TRANSMIT_IDENTIFIER = { 160,161,162,163 }; + public static final int[] TRANSMIT_CHANNEL = { 164,165,166,167,168,169,170, + 171,172,173,174,175 }; + public static final int[] RECEIVE_IDENTIFIER = { 176,177,178,179 }; + public static final int[] RECEIVE_CHANNEL = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] CALL_TIMER = { 192,193,194,195,196,197,198,199, + 200,201,202,203,204,205,206,207 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public TelephoneInterconnectChannelGrantExplicit( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " ADDR:" ); + sb.append( getAddress() ); + + sb.append( " CALL TIMER:" ); + sb.append( mTimeDurationFormat.format( new Date( getCallTimer() ) ) ); + + sb.append( " CHAN DN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append( " " + getDownlinkFrequency() ); + + sb.append( " CHAN UP:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append( " " + getUplinkFrequency() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getAddress() + { + return mMessage.getHex( ADDRESS, 6 ); + } + + /* + * Call timer in milliseconds + */ + public long getCallTimer() + { + int timer = mMessage.getInt( CALL_TIMER ); + + return timer / 100; + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantUpdateExplicit.java b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantUpdateExplicit.java new file mode 100644 index 00000000..f7d6803e --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantUpdateExplicit.java @@ -0,0 +1,22 @@ +package decode.p25.message.pdu.osp.voice; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class TelephoneInterconnectChannelGrantUpdateExplicit + extends TelephoneInterconnectChannelGrantExplicit +{ + public TelephoneInterconnectChannelGrantUpdateExplicit( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE.getDescription(); + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/UnitToUnitAnswerRequestExplicit.java b/src/decode/p25/message/pdu/osp/voice/UnitToUnitAnswerRequestExplicit.java new file mode 100644 index 00000000..308c9d1a --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/UnitToUnitAnswerRequestExplicit.java @@ -0,0 +1,105 @@ +package decode.p25.message.pdu.osp.voice; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class UnitToUnitAnswerRequestExplicit extends PDUMessage +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] TARGET_ADDRESS = { 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[] WACN = { 168,169,170,171,172,173,174,175,176,177, + 178,179,180,181,182,183,184,185,186,187 }; + public static final int[] SYSTEM_ID = { 188,189,190,191,192,193,194,195,196, + 197,198,199 }; + public static final int[] SOURCE_ID = { 200,201,202,203,204,205,206,207,208, + 209,210,211,212,213,214,215,216,217,218,219,220,221,222,223 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 224,225,226,227,228,229, + 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247, + 248,249,250,251,252,253,254,255 }; + + public UnitToUnitAnswerRequestExplicit( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.UNIT_TO_UNIT_ANSWER_REQUEST.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " FROM:" ); + sb.append( getSourceID() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN:" + getWACN() ); + + sb.append( " SYS:" + getSystemID() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getSystemID() + { + return mMessage.getHex( SYSTEM_ID, 3 ); + } + + public String getWACN() + { + return mMessage.getHex( WACN, 6 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 4 ); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantExtended.java b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantExtended.java new file mode 100644 index 00000000..80e785bd --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantExtended.java @@ -0,0 +1,25 @@ +package decode.p25.message.pdu.osp.voice; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.UnitToUnitChannelGrantExtended; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class UnitToUnitVoiceChannelGrantExtended + extends UnitToUnitChannelGrantExtended + implements IdentifierUpdateReceiver +{ + public UnitToUnitVoiceChannelGrantExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.UNIT_TO_UNIT_VOICE_CHANNEL_GRANT.getDescription(); + } +} diff --git a/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java new file mode 100644 index 00000000..bdb51976 --- /dev/null +++ b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java @@ -0,0 +1,191 @@ +package decode.p25.message.pdu.osp.voice; + +import alias.AliasList; +import bits.BitSetBuffer; +import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.tsbk.osp.control.IdentifierUpdate; +import decode.p25.message.tsbk.osp.control.IdentifierUpdateReceiver; +import decode.p25.reference.DataUnitID; +import decode.p25.reference.Opcode; + +public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage + implements IdentifierUpdateReceiver +{ + /* Service Options */ + public static final int EMERGENCY_FLAG = 128; + public static final int ENCRYPTED_CHANNEL_FLAG = 129; + public static final int DUPLEX_MODE = 130; + public static final int SESSION_MODE = 131; + + public static final int[] SOURCE_ADDRESS = { 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[] SERVICE_OPTIONS = { 128,129,130,131,132,133,134, + 135 }; + public static final int[] SOURCE_WACN = { 160,161,162,163,164,165,166,167, + 168,169,170,171,172,173,174,175,176,177,178,179 }; + public static final int[] SOURCE_SYSTEM_ID = { 180,181,182,183,184,185,186, + 187,188,189,190,191 }; + public static final int[] SOURCE_ID = { 192,193,194,195,196,197,198,199,200, + 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215 }; + public static final int[] TARGET_ADDRESS = { 216,217,218,219,220,221,222, + 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239 }; + public static final int[] TRANSMIT_IDENTIFIER = { 240,241,242,243 }; + public static final int[] TRANSMIT_CHANNEL = { 244,245,246,247,248,249,250, + 251,252,253,254,255 }; + public static final int[] RECEIVE_IDENTIFIER = { 256,257,258,259 }; + public static final int[] RECEIVE_CHANNEL = { 260,261,262,263,264,265,266, + 267,268,269,270,271 }; + public static final int[] MULTIPLE_BLOCK_CRC = { 320,321,322,323,324,325, + 326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342, + 343,344,345,346,347,348,349,350,351 }; + + private IdentifierUpdate mTransmitIdentifierUpdate; + private IdentifierUpdate mReceiveIdentifierUpdate; + + public UnitToUnitVoiceChannelGrantUpdateExtended( BitSetBuffer message, + DataUnitID duid, AliasList aliasList ) + { + super( message, duid, aliasList ); + } + + @Override + public String getEventType() + { + return Opcode.UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE.getDescription(); + } + + public String getMessage() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getMessageStub() ); + + if( isEmergency() ) + { + sb.append( " EMERGENCY" ); + } + + sb.append( " FROM ADDR:" ); + sb.append( getSourceAddress() ); + + sb.append( " ID:" ); + sb.append( getSourceID() ); + + sb.append( " TO:" ); + sb.append( getTargetAddress() ); + + sb.append( " WACN:" ); + sb.append( getSourceWACN() ); + + sb.append( " SYS:" ); + sb.append( getSourceSystemID() ); + + sb.append( " CHAN DN:" + getTransmitIdentifier() + "-" + getTransmitChannel() ); + sb.append( " " + getDownlinkFrequency() ); + + sb.append( " CHAN UP:" + getReceiveIdentifier() + "-" + getReceiveChannel() ); + sb.append( " " + getUplinkFrequency() ); + + return sb.toString(); + } + + public boolean isEmergency() + { + return mMessage.get( EMERGENCY_FLAG ); + } + + public boolean isEncryptedChannel() + { + return mMessage.get( ENCRYPTED_CHANNEL_FLAG ); + } + + public DuplexMode getDuplexMode() + { + return mMessage.get( DUPLEX_MODE ) ? DuplexMode.FULL : DuplexMode.HALF; + } + + public SessionMode getSessionMode() + { + return mMessage.get( SESSION_MODE ) ? + SessionMode.CIRCUIT : SessionMode.PACKET; + } + + public String getSourceAddress() + { + return mMessage.getHex( SOURCE_ADDRESS, 6 ); + } + + public String getSourceID() + { + return mMessage.getHex( SOURCE_ID, 6 ); + } + + public String getSourceWACN() + { + return mMessage.getHex( SOURCE_WACN, 5 ); + } + + public String getSourceSystemID() + { + return mMessage.getHex( SOURCE_SYSTEM_ID, 3 ); + } + + public String getTargetAddress() + { + return mMessage.getHex( TARGET_ADDRESS, 6 ); + } + + public int getTransmitIdentifier() + { + return mMessage.getInt( TRANSMIT_IDENTIFIER ); + } + + public int getTransmitChannel() + { + return mMessage.getInt( TRANSMIT_CHANNEL ); + } + + public int getReceiveIdentifier() + { + return mMessage.getInt( RECEIVE_IDENTIFIER ); + } + + public int getReceiveChannel() + { + return mMessage.getInt( RECEIVE_CHANNEL ); + } + + public long getDownlinkFrequency() + { + return calculateDownlink( mTransmitIdentifierUpdate, getTransmitChannel() ); + } + + public long getUplinkFrequency() + { + return calculateUplink( mReceiveIdentifierUpdate, getReceiveChannel() ); + } + + @Override + public void setIdentifierMessage( int identifier, IdentifierUpdate message ) + { + if( identifier == getTransmitIdentifier() ) + { + mTransmitIdentifierUpdate = message; + } + + if( identifier == getReceiveIdentifier() ) + { + mReceiveIdentifierUpdate = message; + } + } + + public int[] getIdentifiers() + { + int[] idens = new int[ 2 ]; + + idens[ 0 ] = getTransmitIdentifier(); + idens[ 1 ] = getReceiveIdentifier(); + + return idens; + } +} diff --git a/src/decode/p25/message/tsbk/ServiceMessage.java b/src/decode/p25/message/tsbk/ServiceMessage.java index ec8aa8e4..694ddec5 100644 --- a/src/decode/p25/message/tsbk/ServiceMessage.java +++ b/src/decode/p25/message/tsbk/ServiceMessage.java @@ -12,9 +12,6 @@ public abstract class ServiceMessage extends TSBKMessage public static final int DUPLEX_MODE = 82; public static final int SESSION_MODE = 83; - public enum DuplexMode { HALF, FULL }; - public enum SessionMode { PACKET, CIRCUIT }; - public ServiceMessage( BitSetBuffer message, DataUnitID duid, AliasList aliasList ) diff --git a/src/decode/p25/message/tsbk/TSBKMessageFactory.java b/src/decode/p25/message/tsbk/TSBKMessageFactory.java index b18631ba..d863a78b 100644 --- a/src/decode/p25/message/tsbk/TSBKMessageFactory.java +++ b/src/decode/p25/message/tsbk/TSBKMessageFactory.java @@ -68,7 +68,7 @@ public class TSBKMessageFactory switch( opcode ) { - case ACKNOWLEDGE_RESPONSE_FNE: + case ACKNOWLEDGE_RESPONSE: return new AcknowledgeResponse( message, duid, aliasList ); case ADJACENT_STATUS_BROADCAST: diff --git a/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java b/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java index 9d52b7a3..9460b3f7 100644 --- a/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java +++ b/src/decode/p25/message/tsbk/osp/control/AcknowledgeResponse.java @@ -30,7 +30,7 @@ public class AcknowledgeResponse extends TSBKMessage @Override public String getEventType() { - return Opcode.ACKNOWLEDGE_RESPONSE_FNE.getDescription(); + return Opcode.ACKNOWLEDGE_RESPONSE.getDescription(); } public String getMessage() diff --git a/src/decode/p25/message/tsbk/osp/voice/GroupVoiceChannelGrant.java b/src/decode/p25/message/tsbk/osp/voice/GroupVoiceChannelGrant.java index d24ec7ae..c60dd62f 100644 --- a/src/decode/p25/message/tsbk/osp/voice/GroupVoiceChannelGrant.java +++ b/src/decode/p25/message/tsbk/osp/voice/GroupVoiceChannelGrant.java @@ -1,6 +1,5 @@ package decode.p25.message.tsbk.osp.voice; -import alias.Alias; import alias.AliasList; import bits.BitSetBuffer; import decode.p25.message.tsbk.GroupChannelGrant; diff --git a/src/decode/p25/reference/Opcode.java b/src/decode/p25/reference/Opcode.java index fa828a45..d5b09c5e 100644 --- a/src/decode/p25/reference/Opcode.java +++ b/src/decode/p25/reference/Opcode.java @@ -34,7 +34,7 @@ public enum Opcode RADIO_UNIT_MONITOR_COMMAND( "RADIO_MONITR_CMD", "Radio Unit Monitor Command", 29 ), RESERVED_1E( "RESERVED_1E ", "Reserved", 30 ), CALL_ALERT( "CALL_ALERT ", "Call Alert", 31 ), - ACKNOWLEDGE_RESPONSE_FNE( "ACK_RESPONSE_FNE", "Acknowledge Response - FNE", 32 ), + ACKNOWLEDGE_RESPONSE( "ACK_RESPONSE_FNE", "Acknowledge Response - FNE", 32 ), QUEUED_RESPONSE( "QUEUED_RESPONSE ", "Queued Response", 33 ), RESERVED_22( "RESERVED_22 ", "Reserved", 34 ), RESERVED_23( "RESERVED_23 ", "Reserved", 35 ),