diff --git a/src/controller/activity/CallEvent.java b/src/controller/activity/CallEvent.java index 235e3c5a..61dd9a5b 100644 --- a/src/controller/activity/CallEvent.java +++ b/src/controller/activity/CallEvent.java @@ -98,6 +98,11 @@ public abstract class CallEvent return mFromID; } + public boolean hasFromID() + { + return mFromID != null; + } + public void setFromID( String id ) { mFromID = id; @@ -108,6 +113,11 @@ public abstract class CallEvent return mToID; } + public boolean hasToID() + { + return mToID != null; + } + public void setToID( String id ) { mToID = id; diff --git a/src/decode/p25/P25ActivitySummary.java b/src/decode/p25/P25ActivitySummary.java index be6fa42d..65ac26fc 100644 --- a/src/decode/p25/P25ActivitySummary.java +++ b/src/decode/p25/P25ActivitySummary.java @@ -34,7 +34,7 @@ import sample.Listener; import alias.Alias; import alias.AliasList; import controller.activity.ActivitySummaryProvider; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.pdu.PDUMessage; import decode.p25.message.pdu.osp.control.NetworkStatusBroadcastExtended; import decode.p25.message.pdu.osp.control.ProtectionParameterBroadcast; @@ -296,7 +296,7 @@ public class P25ActivitySummary implements ActivitySummaryProvider, sb.append( "\nFREQUENCY BANDS:" ); for( Integer id: identifiers ) { - IdentifierProvider band = mBands.get( id ); + IBandIdentifier band = mBands.get( id ); sb.append( "\n\t" + id ); sb.append( "- BASE: " + mFrequencyFormatter.format( diff --git a/src/decode/p25/P25ChannelState.java b/src/decode/p25/P25ChannelState.java index 1dfda056..daa3cbb8 100644 --- a/src/decode/p25/P25ChannelState.java +++ b/src/decode/p25/P25ChannelState.java @@ -20,14 +20,17 @@ package decode.p25; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import source.config.SourceConfigTuner; +import source.config.SourceConfiguration; import alias.Alias; import alias.AliasList; import audio.SquelchListener; @@ -41,9 +44,17 @@ import controller.state.ChannelState; import decode.p25.message.P25Message; import decode.p25.message.hdu.HDUMessage; import decode.p25.message.ldu.LDU1Message; -import decode.p25.message.ldu.LDU2Message; import decode.p25.message.ldu.LDUMessage; +import decode.p25.message.ldu.lc.CallTermination; +import decode.p25.message.ldu.lc.TelephoneInterconnectVoiceChannelUser; +import decode.p25.message.ldu.lc.UnitToUnitVoiceChannelUser; import decode.p25.message.pdu.PDUMessage; +import decode.p25.message.pdu.confirmed.PDUConfirmedMessage; +import decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextAccept; +import decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextReject; +import decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextRequest; +import decode.p25.message.pdu.confirmed.SNDCPDeactivateTDSContext; +import decode.p25.message.pdu.confirmed.SNDCPUserData; import decode.p25.message.pdu.osp.control.CallAlertExtended; import decode.p25.message.pdu.osp.control.GroupAffiliationQueryExtended; import decode.p25.message.pdu.osp.control.GroupAffiliationResponseExtended; @@ -60,6 +71,13 @@ import decode.p25.message.pdu.osp.voice.TelephoneInterconnectChannelGrantExplici 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.message.tdu.lc.AdjacentSiteStatusBroadcast; +import decode.p25.message.tdu.lc.GroupVoiceChannelUpdate; +import decode.p25.message.tdu.lc.GroupVoiceChannelUpdateExplicit; +import decode.p25.message.tdu.lc.NetworkStatusBroadcast; +import decode.p25.message.tdu.lc.NetworkStatusBroadcastExplicit; +import decode.p25.message.tdu.lc.SecondaryControlChannelBroadcast; +import decode.p25.message.tdu.lc.SecondaryControlChannelBroadcastExplicit; import decode.p25.message.tdu.lc.TDULinkControlMessage; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.message.tsbk.osp.control.AcknowledgeResponse; @@ -96,7 +114,8 @@ import decode.p25.message.tsbk.osp.voice.TelephoneInterconnectVoiceChannelGrantU import decode.p25.message.tsbk.osp.voice.UnitToUnitAnswerRequest; import decode.p25.message.tsbk.osp.voice.UnitToUnitVoiceChannelGrant; import decode.p25.message.tsbk.osp.voice.UnitToUnitVoiceChannelGrantUpdate; -import decode.p25.reference.Opcode; +import decode.p25.reference.Encryption; +import decode.p25.reference.IPProtocol; import decode.p25.reference.Response; import decode.p25.reference.Vendor; @@ -104,7 +123,6 @@ public class P25ChannelState extends ChannelState { private final static Logger mLog = LoggerFactory.getLogger( P25ChannelState.class ); - private final static String CURRENT_CHANNEL = "CHANNEL"; private HashMap mRegistrations = new HashMap(); private String mLastCommandEventID; @@ -113,8 +131,8 @@ public class P25ChannelState extends ChannelState private String mLastRegistrationEventID; private String mLastResponseEventID; - private CopyOnWriteArrayList mActiveCalls = - new CopyOnWriteArrayList(); + private ActiveCall mCurrentActiveCall; + private Map mCallDetects = new HashMap(); private P25ActivitySummary mActivitySummary; private String mNAC; @@ -125,12 +143,24 @@ public class P25ChannelState extends ChannelState private String mFromAlias; private String mToTalkgroup; private String mToAlias; + + /* The currently tuned traffic channel - dynamically updated */ + private String mCurrentChannel = "CURRENT"; + private long mCurrentChannelFrequency = 0; public P25ChannelState( ProcessingChain chain, AliasList aliasList ) { super( chain, aliasList ); mActivitySummary = new P25ActivitySummary( aliasList ); + + /* Get the channel frequency from the source config */ + SourceConfiguration source = chain.getChannel().getSourceConfiguration(); + + if( source instanceof SourceConfigTuner ) + { + mCurrentChannelFrequency = ((SourceConfigTuner)source).getFrequency(); + } } public void addListener( SquelchListener listener ) @@ -149,6 +179,8 @@ public class P25ChannelState extends ChannelState if( message instanceof P25Message ) { + updateNAC( ( (P25Message) message ).getNAC() ); + mActivitySummary.receive( (P25Message)message ); if( message instanceof HDUMessage ) @@ -183,15 +215,62 @@ public class P25ChannelState extends ChannelState private void processHDU( HDUMessage hdu ) { - + if( isActiveCall( mCurrentChannel, hdu.getToID() ) ) + { + updateCall( State.CALL, mCurrentChannel, null, hdu.getTalkgroupID() ); + } + else + { + StringBuilder sb = new StringBuilder(); + + if( hdu.getEncryption() != Encryption.UNENCRYPTED ) + { + sb.append( "ENCRYPTED WITH " ); + sb.append( hdu.getEncryption().name() ); + sb.append( " KEY:" ); + sb.append( hdu.getKeyID() ); + } + + P25CallEvent event = new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .frequency( mCurrentChannelFrequency ) + .to( hdu.getToID() ) + .details( sb.toString() ) + .build(); + + addCall( event ); + } } - + + /** + * Processes Terminator Data Unit with Link Control messages that occur on + * the traffic channel + */ private void processTDULC( TDULinkControlMessage tdulc ) { switch( tdulc.getOpcode() ) { + case ADJACENT_SITE_STATUS_BROADCAST: + if( tdulc instanceof AdjacentSiteStatusBroadcast ) + { + AdjacentSiteStatusBroadcast assb = + (AdjacentSiteStatusBroadcast)tdulc; + + updateSystem( assb.getSystemID() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT: + /* This message doesn't provide anything we need for channel state */ + break; case CALL_ALERT: - decode.p25.message.tdu.lc.CallAlert ca = + if( tdulc instanceof decode.p25.message.tdu.lc.CallAlert ) + { + decode.p25.message.tdu.lc.CallAlert ca = (decode.p25.message.tdu.lc.CallAlert)tdulc; mCallEventModel.add( new P25CallEvent.Builder( CallEventType.PAGE ) @@ -200,165 +279,438 @@ public class P25ChannelState extends ChannelState .to( ca.getTargetAddress() ) .details( "CALL ALERT" ) .build() ); - break; - case CALL_TERMINATION_OR_CANCELLATION: - //TODO: terminate all active calls for this channel state - break; - case EXTENDED_FUNCTION_COMMAND: - decode.p25.message.tdu.lc.ExtendedFunctionCommand efc = - (decode.p25.message.tdu.lc.ExtendedFunctionCommand)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( efc.getTargetAddress() ) - .details( "FUNCTION:" + efc.getExtendedFunction().getLabel() + - " ARG:" + efc.getArgument() ) - .build() ); - break; - case GROUP_AFFILIATION_QUERY: - decode.p25.message.tdu.lc.GroupAffiliationQuery gaq = - (decode.p25.message.tdu.lc.GroupAffiliationQuery)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "GROUP AFFILIATION QUERY" ) - .from( gaq.getSourceAddress() ) - .to( gaq.getTargetAddress() ) - .build() ); - break; - case GROUP_VOICE_CHANNEL_UPDATE: - //TODO: process call here - break; - case GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT: - //TODO: process call here - break; - case GROUP_VOICE_CHANNEL_USER: - if( !( tdulc instanceof decode.p25.message.tdu.lc.GroupVoiceChannelUser ) ) - { - mLog.error( "TDULC message has opcode of group voice channel user but is not instance " + tdulc.toString() + " " + tdulc.getBinaryMessage().toString() ); } else { - decode.p25.message.tdu.lc.GroupVoiceChannelUser gvcuser = - (decode.p25.message.tdu.lc.GroupVoiceChannelUser)tdulc; + logAlternateVendorMessage( tdulc ); + } + break; + case CALL_TERMINATION_OR_CANCELLATION: + endAllCalls(); + break; + case CHANNEL_IDENTIFIER_UPDATE: + /* This message is handled by the P25MessageProcessor and + * inserted into any channels needing frequency band info */ + break; + case CHANNEL_IDENTIFIER_UPDATE_EXPLICIT: + /* This message is handled by the P25MessageProcessor and + * inserted into any channels needing frequency band info */ + break; + case EXTENDED_FUNCTION_COMMAND: + if( tdulc instanceof decode.p25.message.tdu.lc.ExtendedFunctionCommand ) + { + decode.p25.message.tdu.lc.ExtendedFunctionCommand efc = + (decode.p25.message.tdu.lc.ExtendedFunctionCommand)tdulc; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( efc.getTargetAddress() ) + .details( "FUNCTION:" + efc.getExtendedFunction().getLabel() + + " ARG:" + efc.getArgument() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case GROUP_AFFILIATION_QUERY: + if( tdulc instanceof decode.p25.message.tdu.lc.GroupAffiliationQuery ) + { + decode.p25.message.tdu.lc.GroupAffiliationQuery gaq = + (decode.p25.message.tdu.lc.GroupAffiliationQuery)tdulc; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "GROUP AFFILIATION QUERY" ) + .from( gaq.getSourceAddress() ) + .to( gaq.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case GROUP_VOICE_CHANNEL_UPDATE: + /* Reflects other call activity on the system: CALL DETECT */ + if( tdulc instanceof GroupVoiceChannelUpdate ) + { + GroupVoiceChannelUpdate gvcu = (GroupVoiceChannelUpdate)tdulc; - if( isActiveCall( CURRENT_CHANNEL, gvcuser.getGroupAddress() ) ) + if( isActiveCall( gvcu.getChannelA(), + gvcu.getGroupAddressA() ) ) { - if( gvcuser.getFromID() != null && - !gvcuser.getFromID().contentEquals( "0000" ) && - !gvcuser.getFromID().contentEquals( "000000" ) ) - { - updateCall( CURRENT_CHANNEL, gvcuser.getSourceAddress(), - gvcuser.getGroupAddress() ); - } - else - { - updateCall( CURRENT_CHANNEL, null, gvcuser.getGroupAddress() ); - } + updateCall( State.CALL, + gvcu.getChannelA(), + gvcu.getGroupAddressA(), + gvcu.getGroupAddressB() ); } else { - CallEvent gvcuserEvent = + P25CallEvent gvcuEvent = + new P25CallEvent.Builder( CallEventType.CALL_DETECT ) + .aliasList( mAliasList ) + .channel( gvcu.getChannelA() ) + .details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) ) + .frequency( gvcu.getDownlinkFrequencyA() ) + .from( gvcu.getGroupAddressA() ) + .to( gvcu.getGroupAddressB() ) + .build(); + + addCall( gvcuEvent ); + } + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT: + /* Reflects other call activity on the system: CALL DETECT */ + + if( tdulc instanceof GroupVoiceChannelUpdateExplicit ) + { + GroupVoiceChannelUpdateExplicit gvcue = + (GroupVoiceChannelUpdateExplicit)tdulc; + if( isActiveCall( gvcue.getTransmitChannel(), + gvcue.getGroupAddress() ) ) + { + updateCall( State.CALL, + gvcue.getTransmitChannel(), + null, + gvcue.getGroupAddress() ); + } + else + { + P25CallEvent gvcueEvent = + new P25CallEvent.Builder( CallEventType.CALL_DETECT ) + .aliasList( mAliasList ) + .channel( gvcue.getTransmitChannel() ) + .details( ( gvcue.isEncrypted() ? "ENCRYPTED" : "" ) ) + .frequency( gvcue.getDownlinkFrequency() ) + .to( gvcue.getGroupAddress() ) + .build(); + + addCall( gvcueEvent ); + } + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case GROUP_VOICE_CHANNEL_USER: + if( tdulc instanceof decode.p25.message.tdu.lc.GroupVoiceChannelUser ) + { + decode.p25.message.tdu.lc.GroupVoiceChannelUser gvcuser = + (decode.p25.message.tdu.lc.GroupVoiceChannelUser)tdulc; + + if( isActiveCall( mCurrentChannel, gvcuser.getGroupAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + gvcuser.getSourceAddress(), + gvcuser.getGroupAddress() ); + } + else + { + P25CallEvent gvcuserEvent = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) - .channel( CURRENT_CHANNEL ) + .channel( mCurrentChannel ) .details( ( gvcuser.isEncrypted() ? "ENCRYPTED" : "" ) + ( gvcuser.isEmergency() ? " EMERGENCY" : "") ) + .frequency( mCurrentChannelFrequency ) .from( gvcuser.getSourceAddress() ) .to( gvcuser.getGroupAddress() ) .build(); - mCallEventModel.add( gvcuserEvent ); - addCall( gvcuserEvent ); - - setState( State.CALL ); } } + else + { + logAlternateVendorMessage( tdulc ); + } break; case MESSAGE_UPDATE: - decode.p25.message.tdu.lc.MessageUpdate mu = - (decode.p25.message.tdu.lc.MessageUpdate)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.SDM ) - .aliasList( mAliasList ) - .from( mu.getSourceAddress() ) - .to( mu.getTargetAddress() ) - .details( "MSG: " + mu.getShortDataMessage() ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.MessageUpdate ) + { + decode.p25.message.tdu.lc.MessageUpdate mu = + (decode.p25.message.tdu.lc.MessageUpdate)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.SDM ) + .aliasList( mAliasList ) + .from( mu.getSourceAddress() ) + .to( mu.getTargetAddress() ) + .details( "MSG: " + mu.getShortDataMessage() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case NETWORK_STATUS_BROADCAST: + if( tdulc instanceof NetworkStatusBroadcast ) + { + updateSystem( ((NetworkStatusBroadcast)tdulc).getSystem() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case NETWORK_STATUS_BROADCAST_EXPLICIT: + if( tdulc instanceof NetworkStatusBroadcastExplicit ) + { + updateSystem( ((NetworkStatusBroadcastExplicit)tdulc).getSystem() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case PROTECTION_PARAMETER_BROADCAST: - decode.p25.message.tdu.lc.ProtectionParameterBroadcast ppb = - (decode.p25.message.tdu.lc.ProtectionParameterBroadcast)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( ppb.getTargetAddress() ) - .details( "ENCRYPTION: " + - ppb.getEncryption().name() + " KEY:" + - ppb.getEncryptionKey() ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.ProtectionParameterBroadcast ) + { + decode.p25.message.tdu.lc.ProtectionParameterBroadcast ppb = + (decode.p25.message.tdu.lc.ProtectionParameterBroadcast)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( ppb.getTargetAddress() ) + .details( "ENCRYPTION: " + + ppb.getEncryption().name() + " KEY:" + + ppb.getEncryptionKey() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case RFSS_STATUS_BROADCAST: + if( tdulc instanceof decode.p25.message.tdu.lc.RFSSStatusBroadcast ) + { + decode.p25.message.tdu.lc.RFSSStatusBroadcast rfsssb = + (decode.p25.message.tdu.lc.RFSSStatusBroadcast)tdulc; + + updateSystem( rfsssb.getSystem() ); + + String site = rfsssb.getRFSubsystemID() + "-" + + rfsssb.getSiteID(); + + updateSite( site ); + +// if( mCurrentChannel == null || +// !mCurrentChannel.contentEquals( rfsssb.getChannel() ) ) +// { +// mCurrentChannel = rfsssb.getChannel(); +// mCurrentChannelFrequency = rfsssb.getDownlinkFrequency(); +// } + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case RFSS_STATUS_BROADCAST_EXPLICIT: + if( tdulc instanceof decode.p25.message.tdu.lc.RFSSStatusBroadcastExplicit ) + { + decode.p25.message.tdu.lc.RFSSStatusBroadcastExplicit rfsssbe = + (decode.p25.message.tdu.lc.RFSSStatusBroadcastExplicit)tdulc; + + String site = rfsssbe.getRFSubsystemID() + "-" + + rfsssbe.getSiteID(); + + updateSite( site ); + +// if( mCurrentChannel == null || +// !mCurrentChannel.contentEquals( rfsssbe.getTransmitChannel() ) ) +// { +// mCurrentChannel = rfsssbe.getTransmitChannel(); +// mCurrentChannelFrequency = rfsssbe.getDownlinkFrequency(); +// } + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case SECONDARY_CONTROL_CHANNEL_BROADCAST: + if( tdulc instanceof SecondaryControlChannelBroadcast ) + { + SecondaryControlChannelBroadcast sccb = + (SecondaryControlChannelBroadcast)tdulc; + + String site = sccb.getRFSubsystemID() + "-" + + sccb.getSiteID(); + + updateSite( site ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT: + if( tdulc instanceof SecondaryControlChannelBroadcastExplicit ) + { + SecondaryControlChannelBroadcastExplicit sccb = + (SecondaryControlChannelBroadcastExplicit)tdulc; + + String site = sccb.getRFSubsystemID() + "-" + + sccb.getSiteID(); + + updateSite( site ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case STATUS_QUERY: - decode.p25.message.tdu.lc.StatusQuery sq = - (decode.p25.message.tdu.lc.StatusQuery)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "STATUS QUERY" ) - .from( sq.getSourceAddress() ) - .to( sq.getTargetAddress() ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.StatusQuery ) + { + decode.p25.message.tdu.lc.StatusQuery sq = + (decode.p25.message.tdu.lc.StatusQuery)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "STATUS QUERY" ) + .from( sq.getSourceAddress() ) + .to( sq.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case STATUS_UPDATE: - decode.p25.message.tdu.lc.StatusUpdate su = - (decode.p25.message.tdu.lc.StatusUpdate)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.STATUS ) - .aliasList( mAliasList ) - .details( "STATUS UNIT:" + su.getUnitStatus() + - " USER:" + su.getUserStatus() ) - .from( su.getSourceAddress() ) - .to( su.getTargetAddress() ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.StatusUpdate ) + { + decode.p25.message.tdu.lc.StatusUpdate su = + (decode.p25.message.tdu.lc.StatusUpdate)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.STATUS ) + .aliasList( mAliasList ) + .details( "STATUS UNIT:" + su.getUnitStatus() + + " USER:" + su.getUserStatus() ) + .from( su.getSourceAddress() ) + .to( su.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } + break; + case SYSTEM_SERVICE_BROADCAST: + /* This message doesn't provide anything we need for channel state */ break; case TELEPHONE_INTERCONNECT_ANSWER_REQUEST: - decode.p25.message.tdu.lc.TelephoneInterconnectAnswerRequest tiar = - (decode.p25.message.tdu.lc.TelephoneInterconnectAnswerRequest)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.PAGE ) - .aliasList( mAliasList ) - .from( tiar.getTelephoneNumber() ) - .to( tiar.getTargetAddress() ) - .details( "TELEPHONE CALL ALERT" ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.TelephoneInterconnectAnswerRequest ) + { + decode.p25.message.tdu.lc.TelephoneInterconnectAnswerRequest tiar = + (decode.p25.message.tdu.lc.TelephoneInterconnectAnswerRequest)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( tiar.getTelephoneNumber() ) + .to( tiar.getTargetAddress() ) + .details( "TELEPHONE CALL ALERT" ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER: - //TODO: process call + if( tdulc instanceof decode.p25.message.tdu.lc.TelephoneInterconnectVoiceChannelUser ) + { + decode.p25.message.tdu.lc.TelephoneInterconnectVoiceChannelUser tivcu = + (decode.p25.message.tdu.lc.TelephoneInterconnectVoiceChannelUser)tdulc; + + if( isActiveCall( mCurrentChannel, tivcu.getAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + null, + tivcu.getAddress() ); + } + else + { + P25CallEvent tivcuEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "TELEPHONE INTERCONNECT " + + ( tivcu.isEncrypted() ? "ENCRYPTED" : "" ) + + ( tivcu.isEmergency() ? " EMERGENCY" : "") ) + .frequency( mCurrentChannelFrequency ) + .from( null ) + .to( tivcu.getAddress() ) + .build(); + + addCall( tivcuEvent ); + } + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case UNIT_AUTHENTICATION_COMMAND: - decode.p25.message.tdu.lc.UnitAuthenticationCommand uac = - (decode.p25.message.tdu.lc.UnitAuthenticationCommand)tdulc; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( uac.getCompleteTargetAddress() ) - .details( "AUTHENTICATE" ) - .build() ); + if( tdulc instanceof decode.p25.message.tdu.lc.UnitAuthenticationCommand ) + { + decode.p25.message.tdu.lc.UnitAuthenticationCommand uac = + (decode.p25.message.tdu.lc.UnitAuthenticationCommand)tdulc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( uac.getCompleteTargetAddress() ) + .details( "AUTHENTICATE" ) + .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case UNIT_REGISTRATION_COMMAND: - decode.p25.message.tdu.lc.UnitRegistrationCommand urc = - (decode.p25.message.tdu.lc.UnitRegistrationCommand)tdulc; + if( tdulc instanceof decode.p25.message.tdu.lc.UnitRegistrationCommand ) + { + decode.p25.message.tdu.lc.UnitRegistrationCommand urc = + (decode.p25.message.tdu.lc.UnitRegistrationCommand)tdulc; + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.COMMAND ) .aliasList( mAliasList ) .to( urc.getCompleteTargetAddress() ) .details( "REGISTER" ) .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case UNIT_TO_UNIT_ANSWER_REQUEST: - decode.p25.message.tdu.lc.UnitToUnitAnswerRequest uuar = - (decode.p25.message.tdu.lc.UnitToUnitAnswerRequest)tdulc; + if( tdulc instanceof decode.p25.message.tdu.lc.UnitToUnitAnswerRequest ) + { + decode.p25.message.tdu.lc.UnitToUnitAnswerRequest uuar = + (decode.p25.message.tdu.lc.UnitToUnitAnswerRequest)tdulc; + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.PAGE ) .aliasList( mAliasList ) @@ -366,160 +718,596 @@ public class P25ChannelState extends ChannelState .to( uuar.getTargetAddress() ) .details( "UNIT TO UNIT CALL ALERT" ) .build() ); + } + else + { + logAlternateVendorMessage( tdulc ); + } break; case UNIT_TO_UNIT_VOICE_CHANNEL_USER: - //TODO: process call here + if( tdulc instanceof decode.p25.message.tdu.lc.UnitToUnitVoiceChannelUser ) + { + decode.p25.message.tdu.lc.UnitToUnitVoiceChannelUser uuvcu = + (decode.p25.message.tdu.lc.UnitToUnitVoiceChannelUser)tdulc; + + if( isActiveCall( mCurrentChannel, uuvcu.getTargetAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + uuvcu.getSourceAddress(), + uuvcu.getTargetAddress() ); + } + else + { + P25CallEvent tivcuEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( ( uuvcu.isEncrypted() ? "ENCRYPTED" : "" ) + + ( uuvcu.isEmergency() ? " EMERGENCY" : "" ) ) + .frequency( mCurrentChannelFrequency ) + .from( uuvcu.getSourceAddress() ) + .to( uuvcu.getTargetAddress() ) + .build(); + + addCall( tivcuEvent ); + } + } + else + { + logAlternateVendorMessage( tdulc ); + } break; - case ADJACENT_SITE_STATUS_BROADCAST: - case ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT: - case CHANNEL_IDENTIFIER_UPDATE: - case CHANNEL_IDENTIFIER_UPDATE_EXPLICIT: - case NETWORK_STATUS_BROADCAST: - case NETWORK_STATUS_BROADCAST_EXPLICIT: - case RFSS_STATUS_BROADCAST: - case RFSS_STATUS_BROADCAST_EXPLICIT: - case SECONDARY_CONTROL_CHANNEL_BROADCAST: - case SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT: - case SYSTEM_SERVICE_BROADCAST: default: break; } } + /** + * Log optional vendor format messages that we don't yet support so that we + * can understand those messages and eventually add support. + */ + private void logAlternateVendorMessage( P25Message p25 ) + { + if( p25 instanceof TDULinkControlMessage ) + { + TDULinkControlMessage tdulc = (TDULinkControlMessage)p25; + + mLog.debug( "TDULC - VENDOR [" + tdulc.getVendor() + + "] SPECIFIC FORMAT FOR " + tdulc.getVendorOpcode().getLabel() + + " " + tdulc.getBinaryMessage() ); + } + else if( p25 instanceof LDU1Message ) + { + LDU1Message ldu1 = (LDU1Message)p25; + + mLog.debug( "LDU1 - VENDOR [" + ldu1.getVendor() + + "] SPECIFIC FORMAT FOR " + ldu1.getVendorOpcode().getLabel() + + " " + ldu1.getBinaryMessage() ); + } + else if( p25 instanceof PDUMessage ) + { + PDUMessage pdu = (PDUMessage)p25; + + mLog.debug( "PDU - VENDOR [" + pdu.getVendor() + + "] SPECIFIC FORMAT FOR " + pdu.getVendorOpcode().getLabel() + + " " + pdu.getBinaryMessage() ); + } + else + { + mLog.debug( "P25 - ALTERNATE VENDOR MESSAGE [" + p25.getClass() + "]" ); + } + } + private void processLDU( LDUMessage ldu ) { if( ldu instanceof LDU1Message ) { switch( ((LDU1Message)ldu).getOpcode() ) { + case ADJACENT_SITE_STATUS_BROADCAST: + if( ldu instanceof decode.p25.message.ldu.lc.AdjacentSiteStatusBroadcast ) + { + decode.p25.message.ldu.lc.AdjacentSiteStatusBroadcast assb = + (decode.p25.message.ldu.lc.AdjacentSiteStatusBroadcast)ldu; + + updateSystem( assb.getSystemID() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT: + /* This message doesn't provide anything we need for channel state */ + updateCall( State.CALL, mCurrentChannel, null, null ); + break; case CALL_ALERT: - decode.p25.message.ldu.lc.CallAlert ca = + if( ldu instanceof decode.p25.message.ldu.lc.CallAlert ) + { + decode.p25.message.ldu.lc.CallAlert ca = (decode.p25.message.ldu.lc.CallAlert)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.PAGE ) - .aliasList( mAliasList ) - .from( ca.getSourceAddress() ) - .to( ca.getTargetAddress() ) - .details( "CALL ALERT" ) - .build() ); + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( ca.getSourceAddress() ) + .to( ca.getTargetAddress() ) + .details( "CALL ALERT" ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + updateCall( State.CALL, mCurrentChannel, null, null ); break; case CALL_TERMINATION_OR_CANCELLATION: - //TODO: terminate all active calls for this channel state + if( ldu instanceof CallTermination ) + { + endAllCalls(); + } + else + { + logAlternateVendorMessage( ldu ); + } + break; + case CHANNEL_IDENTIFIER_UPDATE: + /* This message is handled by the P25MessageProcessor and + * inserted into any channels needing frequency band info */ + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case CHANNEL_IDENTIFIER_UPDATE_EXPLICIT: + /* This message is handled by the P25MessageProcessor and + * inserted into any channels needing frequency band info */ + updateCall( State.CALL, mCurrentChannel, null, null ); break; case EXTENDED_FUNCTION_COMMAND: - decode.p25.message.ldu.lc.ExtendedFunctionCommand efc = - (decode.p25.message.ldu.lc.ExtendedFunctionCommand)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( efc.getTargetAddress() ) - .details( "FUNCTION:" + efc.getExtendedFunction().getLabel() + - " ARG:" + efc.getArgument() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.ExtendedFunctionCommand ) + { + decode.p25.message.ldu.lc.ExtendedFunctionCommand efc = + (decode.p25.message.ldu.lc.ExtendedFunctionCommand)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( efc.getTargetAddress() ) + .details( "FUNCTION:" + efc.getExtendedFunction().getLabel() + + " ARG:" + efc.getArgument() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + updateCall( State.CALL, mCurrentChannel, null, null ); break; case GROUP_AFFILIATION_QUERY: - decode.p25.message.ldu.lc.GroupAffiliationQuery gaq = - (decode.p25.message.ldu.lc.GroupAffiliationQuery)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "GROUP AFFILIATION QUERY" ) - .from( gaq.getSourceAddress() ) - .to( gaq.getTargetAddress() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.GroupAffiliationQuery ) + { + decode.p25.message.ldu.lc.GroupAffiliationQuery gaq = + (decode.p25.message.ldu.lc.GroupAffiliationQuery)ldu; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "GROUP AFFILIATION QUERY" ) + .from( gaq.getSourceAddress() ) + .to( gaq.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + updateCall( State.CALL, mCurrentChannel, null, null ); break; case GROUP_VOICE_CHANNEL_UPDATE: - //TODO: process call here + if( ldu instanceof decode.p25.message.ldu.lc.GroupVoiceChannelUpdate ) + { + decode.p25.message.ldu.lc.GroupVoiceChannelUpdate gvcu = + (decode.p25.message.ldu.lc.GroupVoiceChannelUpdate)ldu; + + if( isActiveCall( gvcu.getChannelA(), + gvcu.getGroupAddressA() ) ) + { + updateCall( State.CALL, + gvcu.getChannelA(), + gvcu.getGroupAddressA(), + gvcu.getGroupAddressB() ); + } + else + { + P25CallEvent gvcuEvent = + new P25CallEvent.Builder( CallEventType.CALL_DETECT ) + .aliasList( mAliasList ) + .channel( gvcu.getChannelA() ) + .details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) ) + .frequency( gvcu.getDownlinkFrequencyA() ) + .from( gvcu.getGroupAddressA() ) + .to( gvcu.getGroupAddressB() ) + .build(); + + addCall( gvcuEvent ); + } + } + else + { + logAlternateVendorMessage( ldu ); + } break; case GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT: - //TODO: process call here + if( ldu instanceof decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit ) + { + decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit gvcue = + (decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit)ldu; + + if( isActiveCall( gvcue.getTransmitChannel(), + gvcue.getGroupAddress() ) ) + { + updateCall( State.CALL, + gvcue.getTransmitChannel(), + null, + gvcue.getGroupAddress() ); + } + else + { + P25CallEvent gvcueEvent = + new P25CallEvent.Builder( CallEventType.CALL_DETECT ) + .aliasList( mAliasList ) + .channel( gvcue.getTransmitChannel() ) + .details( ( gvcue.isEncrypted() ? "ENCRYPTED" : "" ) ) + .frequency( gvcue.getDownlinkFrequency() ) + .to( gvcue.getGroupAddress() ) + .build(); + + addCall( gvcueEvent ); + } + } + else + { + logAlternateVendorMessage( ldu ); + } break; case GROUP_VOICE_CHANNEL_USER: - //TODO: process call here + if( ldu instanceof decode.p25.message.ldu.lc.GroupVoiceChannelUser ) + { + decode.p25.message.ldu.lc.GroupVoiceChannelUser gvcuser = + (decode.p25.message.ldu.lc.GroupVoiceChannelUser)ldu; + + if( isActiveCall( mCurrentChannel, gvcuser.getGroupAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + gvcuser.getSourceAddress(), + gvcuser.getGroupAddress() ); + } + else + { + P25CallEvent gvcuserEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( ( gvcuser.isEncrypted() ? "ENCRYPTED" : "" ) + + ( gvcuser.isEmergency() ? " EMERGENCY" : "") ) + .frequency( mCurrentChannelFrequency ) + .from( gvcuser.getSourceAddress() ) + .to( gvcuser.getGroupAddress() ) + .build(); + + addCall( gvcuserEvent ); + } + } + else + { + logAlternateVendorMessage( ldu ); + } break; case MESSAGE_UPDATE: - decode.p25.message.ldu.lc.MessageUpdate mu = - (decode.p25.message.ldu.lc.MessageUpdate)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.SDM ) - .aliasList( mAliasList ) - .from( mu.getSourceAddress() ) - .to( mu.getTargetAddress() ) - .details( "MSG: " + mu.getShortDataMessage() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.MessageUpdate ) + { + decode.p25.message.ldu.lc.MessageUpdate mu = + (decode.p25.message.ldu.lc.MessageUpdate)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.SDM ) + .aliasList( mAliasList ) + .from( mu.getSourceAddress() ) + .to( mu.getTargetAddress() ) + .details( "MSG: " + mu.getShortDataMessage() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case NETWORK_STATUS_BROADCAST: + if( ldu instanceof decode.p25.message.ldu.lc.NetworkStatusBroadcast ) + { + updateSystem( ((decode.p25.message.ldu.lc.NetworkStatusBroadcast)ldu).getSystem() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case NETWORK_STATUS_BROADCAST_EXPLICIT: + if( ldu instanceof decode.p25.message.ldu.lc.NetworkStatusBroadcastExplicit ) + { + updateSystem( ((decode.p25.message.ldu.lc.NetworkStatusBroadcastExplicit)ldu).getSystem() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case PROTECTION_PARAMETER_BROADCAST: - decode.p25.message.ldu.lc.ProtectionParameterBroadcast ppb = - (decode.p25.message.ldu.lc.ProtectionParameterBroadcast)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( ppb.getTargetAddress() ) - .details( "ENCRYPTION: " + - ppb.getEncryption().name() + " KEY:" + - ppb.getEncryptionKey() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.ProtectionParameterBroadcast ) + { + decode.p25.message.ldu.lc.ProtectionParameterBroadcast ppb = + (decode.p25.message.ldu.lc.ProtectionParameterBroadcast)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( ppb.getTargetAddress() ) + .details( "ENCRYPTION: " + + ppb.getEncryption().name() + " KEY:" + + ppb.getEncryptionKey() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case RFSS_STATUS_BROADCAST: + if( ldu instanceof decode.p25.message.ldu.lc.RFSSStatusBroadcast ) + { + decode.p25.message.ldu.lc.RFSSStatusBroadcast rfsssb = + (decode.p25.message.ldu.lc.RFSSStatusBroadcast)ldu; + + updateSystem( rfsssb.getSystem() ); + + String site = rfsssb.getRFSubsystemID() + "-" + + rfsssb.getSiteID(); + + updateSite( site ); + + if( mCurrentChannel == null || + !mCurrentChannel.contentEquals( rfsssb.getChannel() ) ) + { + mCurrentChannel = rfsssb.getChannel(); + mCurrentChannelFrequency = rfsssb.getDownlinkFrequency(); + } + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case RFSS_STATUS_BROADCAST_EXPLICIT: + if( ldu instanceof decode.p25.message.ldu.lc.RFSSStatusBroadcastExplicit ) + { + decode.p25.message.ldu.lc.RFSSStatusBroadcastExplicit rfsssbe = + (decode.p25.message.ldu.lc.RFSSStatusBroadcastExplicit)ldu; + + String site = rfsssbe.getRFSubsystemID() + "-" + + rfsssbe.getSiteID(); + + updateSite( site ); + + if( mCurrentChannel == null || + !mCurrentChannel.contentEquals( rfsssbe.getTransmitChannel() ) ) + { + mCurrentChannel = rfsssbe.getTransmitChannel(); + mCurrentChannelFrequency = rfsssbe.getDownlinkFrequency(); + } + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case SECONDARY_CONTROL_CHANNEL_BROADCAST: + if( ldu instanceof decode.p25.message.ldu.lc.SecondaryControlChannelBroadcast ) + { + decode.p25.message.ldu.lc.SecondaryControlChannelBroadcast sccb = + (decode.p25.message.ldu.lc.SecondaryControlChannelBroadcast)ldu; + + String site = sccb.getRFSubsystemID() + "-" + + sccb.getSiteID(); + + updateSite( site ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + break; + case SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT: + if( ldu instanceof decode.p25.message.ldu.lc.SecondaryControlChannelBroadcastExplicit ) + { + decode.p25.message.ldu.lc.SecondaryControlChannelBroadcastExplicit sccb = + (decode.p25.message.ldu.lc.SecondaryControlChannelBroadcastExplicit)ldu; + + String site = sccb.getRFSubsystemID() + "-" + + sccb.getSiteID(); + + updateSite( site ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case STATUS_QUERY: - decode.p25.message.ldu.lc.StatusQuery sq = - (decode.p25.message.ldu.lc.StatusQuery)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "STATUS QUERY" ) - .from( sq.getSourceAddress() ) - .to( sq.getTargetAddress() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.StatusQuery ) + { + decode.p25.message.ldu.lc.StatusQuery sq = + (decode.p25.message.ldu.lc.StatusQuery)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "STATUS QUERY" ) + .from( sq.getSourceAddress() ) + .to( sq.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case STATUS_UPDATE: - decode.p25.message.ldu.lc.StatusUpdate su = - (decode.p25.message.ldu.lc.StatusUpdate)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.STATUS ) - .aliasList( mAliasList ) - .details( "STATUS UNIT:" + su.getUnitStatus() + - " USER:" + su.getUserStatus() ) - .from( su.getSourceAddress() ) - .to( su.getTargetAddress() ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.StatusUpdate ) + { + decode.p25.message.ldu.lc.StatusUpdate su = + (decode.p25.message.ldu.lc.StatusUpdate)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.STATUS ) + .aliasList( mAliasList ) + .details( "STATUS UNIT:" + su.getUnitStatus() + + " USER:" + su.getUserStatus() ) + .from( su.getSourceAddress() ) + .to( su.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); + + break; + case SYSTEM_SERVICE_BROADCAST: + /* This message doesn't provide anything we need for channel state */ + updateCall( State.CALL, mCurrentChannel, null, null ); break; case TELEPHONE_INTERCONNECT_ANSWER_REQUEST: - decode.p25.message.ldu.lc.TelephoneInterconnectAnswerRequest tiar = - (decode.p25.message.ldu.lc.TelephoneInterconnectAnswerRequest)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.PAGE ) - .aliasList( mAliasList ) - .from( tiar.getTelephoneNumber() ) - .to( tiar.getTargetAddress() ) - .details( "TELEPHONE CALL ALERT" ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.TelephoneInterconnectAnswerRequest ) + { + decode.p25.message.ldu.lc.TelephoneInterconnectAnswerRequest tiar = + (decode.p25.message.ldu.lc.TelephoneInterconnectAnswerRequest)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( tiar.getTelephoneNumber() ) + .to( tiar.getTargetAddress() ) + .details( "TELEPHONE CALL ALERT" ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER: - //TODO: process call + if( ldu instanceof TelephoneInterconnectVoiceChannelUser ) + { + TelephoneInterconnectVoiceChannelUser tivcu = + (TelephoneInterconnectVoiceChannelUser)ldu; + + if( isActiveCall( mCurrentChannel, tivcu.getAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + null, + tivcu.getAddress() ); + } + else + { + P25CallEvent tivcuEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "TELEPHONE INTERCONNECT " + + ( tivcu.isEncrypted() ? "ENCRYPTED" : "" ) + + ( tivcu.isEmergency() ? " EMERGENCY" : "") ) + .frequency( mCurrentChannelFrequency ) + .from( null ) + .to( tivcu.getAddress() ) + .build(); + + addCall( tivcuEvent ); + } + } + else + { + logAlternateVendorMessage( ldu ); + } break; case UNIT_AUTHENTICATION_COMMAND: - decode.p25.message.ldu.lc.UnitAuthenticationCommand uac = - (decode.p25.message.ldu.lc.UnitAuthenticationCommand)ldu; - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.COMMAND ) - .aliasList( mAliasList ) - .to( uac.getCompleteTargetAddress() ) - .details( "AUTHENTICATE" ) - .build() ); + if( ldu instanceof decode.p25.message.ldu.lc.UnitAuthenticationCommand ) + { + decode.p25.message.ldu.lc.UnitAuthenticationCommand uac = + (decode.p25.message.ldu.lc.UnitAuthenticationCommand)ldu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .to( uac.getCompleteTargetAddress() ) + .details( "AUTHENTICATE" ) + .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case UNIT_REGISTRATION_COMMAND: - decode.p25.message.ldu.lc.UnitRegistrationCommand urc = - (decode.p25.message.ldu.lc.UnitRegistrationCommand)ldu; + if( ldu instanceof decode.p25.message.ldu.lc.UnitRegistrationCommand ) + { + decode.p25.message.ldu.lc.UnitRegistrationCommand urc = + (decode.p25.message.ldu.lc.UnitRegistrationCommand)ldu; + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.COMMAND ) .aliasList( mAliasList ) .to( urc.getCompleteTargetAddress() ) .details( "REGISTER" ) .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case UNIT_TO_UNIT_ANSWER_REQUEST: - decode.p25.message.ldu.lc.UnitToUnitAnswerRequest uuar = - (decode.p25.message.ldu.lc.UnitToUnitAnswerRequest)ldu; + if( ldu instanceof decode.p25.message.ldu.lc.UnitToUnitAnswerRequest ) + { + decode.p25.message.ldu.lc.UnitToUnitAnswerRequest uuar = + (decode.p25.message.ldu.lc.UnitToUnitAnswerRequest)ldu; + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.PAGE ) .aliasList( mAliasList ) @@ -527,30 +1315,57 @@ public class P25ChannelState extends ChannelState .to( uuar.getTargetAddress() ) .details( "UNIT TO UNIT CALL ALERT" ) .build() ); + } + else + { + logAlternateVendorMessage( ldu ); + } + + updateCall( State.CALL, mCurrentChannel, null, null ); break; case UNIT_TO_UNIT_VOICE_CHANNEL_USER: - //TODO: process call here + if( ldu instanceof UnitToUnitVoiceChannelUser ) + { + UnitToUnitVoiceChannelUser uuvcu = + (UnitToUnitVoiceChannelUser)ldu; + + if( isActiveCall( mCurrentChannel, uuvcu.getTargetAddress() ) ) + { + updateCall( State.CALL, + mCurrentChannel, + uuvcu.getSourceAddress(), + uuvcu.getTargetAddress() ); + } + else + { + P25CallEvent tivcuEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( ( uuvcu.isEncrypted() ? "ENCRYPTED" : "" ) + + ( uuvcu.isEmergency() ? " EMERGENCY" : "" ) ) + .frequency( mCurrentChannelFrequency ) + .from( uuvcu.getSourceAddress() ) + .to( uuvcu.getTargetAddress() ) + .build(); + + addCall( tivcuEvent ); + } + } + else + { + logAlternateVendorMessage( ldu ); + } break; - case ADJACENT_SITE_STATUS_BROADCAST: - case ADJACENT_SITE_STATUS_BROADCAST_EXPLICIT: - case CHANNEL_IDENTIFIER_UPDATE: - case CHANNEL_IDENTIFIER_UPDATE_EXPLICIT: - case NETWORK_STATUS_BROADCAST: - case NETWORK_STATUS_BROADCAST_EXPLICIT: - case RFSS_STATUS_BROADCAST: - case RFSS_STATUS_BROADCAST_EXPLICIT: - case SECONDARY_CONTROL_CHANNEL_BROADCAST: - case SECONDARY_CONTROL_CHANNEL_BROADCAST_EXPLICIT: - case SYSTEM_SERVICE_BROADCAST: default: break; } } - else if( ldu instanceof LDU2Message ) + else { - + //LDU2 + updateCall( State.CALL, mCurrentChannel, null, null ); } - } /** @@ -646,53 +1461,599 @@ public class P25ChannelState extends ChannelState /** * Process a Packet Data Unit message */ - private void processPDU( PDUMessage message ) + private void processPDU( PDUMessage pdu ) { - switch( message.getOpcode() ) + if( pdu instanceof PDUConfirmedMessage ) { - case CALL_ALERT: - processPDUCall( message ); - break; - case GROUP_AFFILIATION_QUERY: - processQuery( message ); - break; - case GROUP_AFFILIATION_RESPONSE: - processResponse( message ); - break; - case GROUP_DATA_CHANNEL_GRANT: - case GROUP_VOICE_CHANNEL_GRANT: - case INDIVIDUAL_DATA_CHANNEL_GRANT: - processPDUCall( message ); - break; - case MESSAGE_UPDATE: - processMessage( message ); - break; - case RFSS_STATUS_BROADCAST: - processRFSSStatus( (RFSSStatusBroadcastExtended)message ); - break; - case ROAMING_ADDRESS_UPDATE: - processResponse( message ); - break; - case STATUS_QUERY: - processQuery( message ); - break; - case STATUS_UPDATE: - processResponse( message ); - break; - case UNIT_TO_UNIT_ANSWER_REQUEST: - processPage( message ); - break; - case UNIT_REGISTRATION_RESPONSE: - processResponse( message ); - break; - default: - break; + PDUConfirmedMessage pduc = (PDUConfirmedMessage)pdu; + + switch( pduc.getPDUType() ) + { + case SN_ACTIVATE_TDS_CONTEXT_ACCEPT: + SNDCPActivateTDSContextAccept satca = + (SNDCPActivateTDSContextAccept)pduc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "ACTIVATE SNDCP USE IP:" + satca.getIPAddress() ) + .frequency( mCurrentChannelFrequency ) + .to( satca.getLogicalLinkID() ) + .build() ); + break; + case SN_ACTIVATE_TDS_CONTEXT_REJECT: + SNDCPActivateTDSContextReject satcr = + (SNDCPActivateTDSContextReject)pduc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.COMMAND ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "REJECT: SNDCP CONTEXT ACTIVATION " + + "REASON:" + satcr.getReason().getLabel() ) + .frequency( mCurrentChannelFrequency ) + .to( satcr.getLogicalLinkID() ) + .build() ); + break; + case SN_ACTIVATE_TDS_CONTEXT_REQUEST: + SNDCPActivateTDSContextRequest satcreq = + (SNDCPActivateTDSContextRequest)pduc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "REQUEST SNDCP USE IP:" + satcreq.getIPAddress() ) + .frequency( mCurrentChannelFrequency ) + .from( satcreq.getLogicalLinkID() ) + .build() ); + break; + case SN_DEACTIVATE_TDS_CONTEXT_ACCEPT: + SNDCPDeactivateTDSContext sdtca = + (SNDCPDeactivateTDSContext)pduc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "ACCEPT DEACTIVATE SNDCP CONTEXT" ) + .frequency( mCurrentChannelFrequency ) + .from( sdtca.getLogicalLinkID() ) + .build() ); + break; + case SN_DEACTIVATE_TDS_CONTEXT_REQUEST: + SNDCPDeactivateTDSContext sdtcreq = + (SNDCPDeactivateTDSContext)pduc; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "REQUEST DEACTIVATE SNDCP CONTEXT" ) + .frequency( mCurrentChannelFrequency ) + .from( sdtcreq.getLogicalLinkID() ) + .build() ); + break; + case SN_RF_CONFIRMED_DATA: + SNDCPUserData sud = (SNDCPUserData)pduc; + + StringBuilder sbFrom = new StringBuilder(); + StringBuilder sbTo = new StringBuilder(); + + sbFrom.append( sud.getSourceIPAddress() ); + sbTo.append( sud.getDestinationIPAddress() ); + + if( sud.getIPProtocol() == IPProtocol.UDP ) + { + sbFrom.append( ":" ); + sbFrom.append( sud.getUDPSourcePort() ); + sbTo.append( ":" ); + sbTo.append( sud.getUDPDestinationPort() ); + } + + P25CallEvent dataEvent = new P25CallEvent.Builder( CallEventType.DATA_CALL ) + .aliasList( mAliasList ) + .channel( mCurrentChannel ) + .details( "DATA: " + sud.getPayload() + + " RADIO IP:" + sbTo.toString() ) + .frequency( mCurrentChannelFrequency ) + .from( sbFrom.toString() ) + .to( pduc.getLogicalLinkID() ) + .build(); + + if( isActiveCall( mCurrentChannel, pduc.getLogicalLinkID() ) ) + { + updateCall( State.DATA, mCurrentChannel, sbFrom.toString(), pduc.getLogicalLinkID() ); + } + else + { + addCall( dataEvent ); + } + break; + default: + mLog.debug( "PDUC - Unrecognized Message: " + pduc.toString() ); + break; + } + } + else + { + switch( pdu.getOpcode() ) + { + case CALL_ALERT: + if( pdu instanceof CallAlertExtended ) + { + CallAlertExtended ca = (CallAlertExtended)pdu; + + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( ca.getWACN() + "-" + ca.getSystemID() + "-" + + ca.getSourceID() ) + .to( ca.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case GROUP_AFFILIATION_QUERY: + if( pdu instanceof GroupAffiliationQueryExtended ) + { + GroupAffiliationQueryExtended gaqe = + (GroupAffiliationQueryExtended)pdu; + + if( mLastQueryEventID == null || !gaqe.getTargetAddress() + .contentEquals( mLastQueryEventID ) ) + { + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "GROUP AFFILIATION" ) + .from( gaqe.getWACN() + "-" + gaqe.getSystemID() + + "-" + gaqe.getSourceID() ) + .to( gaqe.getTargetAddress() ) + .build() ); + + mLastQueryEventID = gaqe.getToID(); + } + } + break; + case GROUP_AFFILIATION_RESPONSE: + if( pdu instanceof GroupAffiliationResponseExtended ) + { + GroupAffiliationResponseExtended gar = + (GroupAffiliationResponseExtended)pdu; + + if( mLastResponseEventID == null || !gar.getTargetAddress() + .contentEquals( mLastResponseEventID ) ) + { + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.RESPONSE ) + .aliasList( mAliasList ) + .details( "AFFILIATION:" + gar.getResponse().name() + + " FOR GROUP:" + gar.getGroupWACN() + "-" + + gar.getGroupSystemID() + "-" + + gar.getGroupID() + " ANNOUNCEMENT GROUP:" + + gar.getAnnouncementGroupID() ) + .from( gar.getSourceWACN() + "-" + + gar.getSourceSystemID() + "-" + + gar.getSourceID() ) + .to( gar.getTargetAddress() ) + .build() ); + + mLastResponseEventID = gar.getTargetAddress(); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case GROUP_DATA_CHANNEL_GRANT: + if( pdu instanceof GroupDataChannelGrantExtended ) + { + GroupDataChannelGrantExtended gdcge = + (GroupDataChannelGrantExtended)pdu; + + if( isActiveCall( gdcge.getTransmitChannel(), gdcge.getGroupAddress() ) ) + { + updateCall( State.DATA, + gdcge.getTransmitChannel(), + gdcge.getSourceAddress(), + gdcge.getGroupAddress() ); + } + else + { + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.DATA_CALL ) + .aliasList( mAliasList ) + .channel( gdcge.getTransmitChannel() ) + .details( ( gdcge.isEncrypted() ? "ENCRYPTED" : "" ) + + ( gdcge.isEmergency() ? " EMERGENCY" : "") ) + .frequency( gdcge.getDownlinkFrequency() ) + .from( gdcge.getSourceAddress() ) + .to( gdcge.getGroupAddress() ) + .build(); + + addCall( event ); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case GROUP_VOICE_CHANNEL_GRANT: + if( pdu instanceof GroupVoiceChannelGrantExplicit ) + { + GroupVoiceChannelGrantExplicit gvcge = + (GroupVoiceChannelGrantExplicit)pdu; + + if( isActiveCall( gvcge.getTransmitChannel(), gvcge.getGroupAddress() ) ) + { + updateCall( State.CALL, + gvcge.getTransmitChannel(), + gvcge.getSourceAddress(), + gvcge.getGroupAddress() ); + } + else + { + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( gvcge.getTransmitChannel() ) + .details( ( gvcge.isEncrypted() ? "ENCRYPTED" : "" ) + + ( gvcge.isEmergency() ? " EMERGENCY" : "") ) + .frequency( gvcge.getDownlinkFrequency() ) + .from( gvcge.getSourceAddress() ) + .to( gvcge.getGroupAddress() ) + .build(); + + addCall( event ); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case INDIVIDUAL_DATA_CHANNEL_GRANT: + if( pdu instanceof IndividualDataChannelGrantExtended ) + { + IndividualDataChannelGrantExtended idcge = + (IndividualDataChannelGrantExtended)pdu; + + if( isActiveCall( idcge.getTransmitChannel(), + idcge.getTargetAddress() ) ) + { + updateCall( State.DATA, + idcge.getTransmitChannel(), + idcge.getSourceAddress(), + idcge.getTargetAddress() ); + } + else + { + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.DATA_CALL ) + .aliasList( mAliasList ) + .channel( idcge.getTransmitChannel() ) + .details( ( idcge.isEncrypted() ? "ENCRYPTED" : "" ) + + ( idcge.isEmergency() ? " EMERGENCY" : "") ) + .frequency( idcge.getDownlinkFrequency() ) + .from( idcge.getSourceWACN() + "-" + + idcge.getSourceSystemID() + "-" + + idcge.getSourceAddress() ) + .to( idcge.getTargetAddress() ) + .build(); + + addCall( event ); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case MESSAGE_UPDATE: + if( pdu instanceof MessageUpdateExtended ) + { + MessageUpdateExtended mu = (MessageUpdateExtended)pdu; + + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.SDM ) + .aliasList( mAliasList ) + .details( "MESSAGE: " + mu.getMessage() ) + .from( mu.getSourceWACN() + "-" + mu.getSourceSystemID() + + "-" + mu.getSourceID() ) + .to( mu.getTargetAddress() ) + .build(); + + mCallEventModel.add( event ); + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case RFSS_STATUS_BROADCAST: + if( pdu instanceof RFSSStatusBroadcastExtended ) + { + RFSSStatusBroadcastExtended rsbe = (RFSSStatusBroadcastExtended)pdu; + + updateNAC( rsbe.getNAC() ); + updateSystem( rsbe.getSystemID() ); + updateSite( rsbe.getRFSubsystemID() + "-" + rsbe.getSiteID() ); + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case ROAMING_ADDRESS_UPDATE: + if( pdu instanceof RoamingAddressUpdateExtended ) + { + RoamingAddressUpdateExtended raue = + (RoamingAddressUpdateExtended)pdu; + + StringBuilder sb = new StringBuilder(); + sb.append( "ROAMING ADDRESS STACK A:" ); + sb.append( raue.getWACNA() + "-" + raue.getSystemIDA() ); + + if( raue.isFormat2() ) + { + sb.append( " B:" ); + sb.append( raue.getWACNB() + "-" + raue.getSystemIDB() ); + sb.append( " C:" ); + sb.append( raue.getWACNC() + "-" + raue.getSystemIDC() ); + sb.append( " D:" ); + sb.append( raue.getWACND() + "-" + raue.getSystemIDD() ); + } + + if( raue.isFormat3() ) + { + sb.append( " E:" ); + sb.append( raue.getWACNE() + "-" + raue.getSystemIDE() ); + sb.append( " F:" ); + sb.append( raue.getWACNF() + "-" + raue.getSystemIDF() ); + sb.append( " G:" ); + sb.append( raue.getWACNG() + "-" + raue.getSystemIDG() ); + } + + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.RESPONSE ) + .aliasList( mAliasList ) + .details( sb.toString() ) + .from( raue.getSourceID() ) + .to( raue.getTargetAddress() ) + .build() ); + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case STATUS_QUERY: + if( pdu instanceof StatusQueryExtended ) + { + StatusQueryExtended sq = (StatusQueryExtended)pdu; + + if( mLastQueryEventID == null || !sq.getTargetAddress() + .contentEquals( mLastQueryEventID ) ) + { + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.QUERY ) + .aliasList( mAliasList ) + .details( "STATUS QUERY" ) + .from( sq.getSourceWACN() + "-" + + sq.getSourceSystemID() + "-" + + sq.getSourceID() ) + .to( sq.getTargetAddress() ) + .build() ); + + mLastQueryEventID = sq.getToID(); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case STATUS_UPDATE: + if( pdu instanceof StatusUpdateExtended ) + { + StatusUpdateExtended su = (StatusUpdateExtended)pdu; + + if( mLastResponseEventID == null || !mLastResponseEventID + .contentEquals( su.getTargetAddress() ) ) + { + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.RESPONSE ) + .aliasList( mAliasList ) + .details( "STATUS USER: " + su.getUserStatus() + + " UNIT: " + su.getUnitStatus() ) + .from( su.getSourceWACN() + "-" + + su.getSourceSystemID() + "-" + + su.getSourceID() ) + .to( su.getTargetAddress() ) + .build() ); + + mLastResponseEventID = su.getTargetAddress(); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: + TelephoneInterconnectChannelGrantExplicit ticge = + (TelephoneInterconnectChannelGrantExplicit)pdu; + + if( isActiveCall( ticge.getTransmitChannel(), ticge.getAddress() )) + { + updateCall( State.CALL, + ticge.getTransmitChannel(), + ticge.getLogicalLinkID(), + ticge.getAddress() ); + } + else + { + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( ticge.getTransmitChannel() ) + .details( "TELEPHONE CALL " + + ( ticge.isEncrypted() ? "ENCRYPTED" : "" ) + + ( ticge.isEmergency() ? " EMERGENCY" : "") + + " CALL TIMER:" + ticge.getCallTimer() ) + .frequency( ticge.getDownlinkFrequency() ) + .from( ticge.getAddress() ) + .build(); + + addCall( event ); + } + break; + case UNIT_REGISTRATION_RESPONSE: + if( pdu instanceof UnitRegistrationResponseExtended ) + { + UnitRegistrationResponseExtended urr = + (UnitRegistrationResponseExtended)pdu; + + if( urr.getResponse() == Response.ACCEPT ) + { + mRegistrations.put( urr.getAssignedSourceAddress(), + System.currentTimeMillis() ); + } + + if( mLastRegistrationEventID == null || !mLastRegistrationEventID + .contentEquals( urr.getAssignedSourceAddress() ) ) + { + mCallEventModel.add( new P25CallEvent.Builder( CallEventType.REGISTER ) + .aliasList( mAliasList ) + .details( "REGISTRATION:" + urr.getResponse().name() + + " FOR EXTERNAL SYSTEM ADDRESS: " + + urr.getWACN() + "-" + + urr.getSystemID() + "-" + + urr.getSourceAddress() + + " SOURCE ID: " + urr.getSourceID() ) + .from( urr.getAssignedSourceAddress() ) + .build() ); + + mLastRegistrationEventID = urr.getAssignedSourceAddress(); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case UNIT_TO_UNIT_ANSWER_REQUEST: + if( pdu instanceof UnitToUnitAnswerRequestExplicit ) + { + UnitToUnitAnswerRequestExplicit utuare = + (UnitToUnitAnswerRequestExplicit)pdu; + + if( mLastPageEventID == null || !mLastPageEventID + .contentEquals( utuare.getTargetAddress() ) ) + { + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .details( ( utuare.isEmergency() ? "EMERGENCY" : "" ) ) + .from( utuare.getWACN() + "-" + + utuare.getSystemID() + "-" + + utuare.getSourceID() ) + .to( utuare.getTargetAddress() ) + .build() ); + + mLastPageEventID = utuare.getTargetAddress(); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: + if( pdu instanceof UnitToUnitVoiceChannelGrantExtended ) + { + UnitToUnitVoiceChannelGrantExtended uuvcge = + (UnitToUnitVoiceChannelGrantExtended)pdu; + + if( isActiveCall( uuvcge.getTransmitChannel(), uuvcge.getTargetAddress() ) ) + { + updateCall( State.CALL, + uuvcge.getTransmitChannel(), + uuvcge.getSourceAddress(), + uuvcge.getTargetAddress() ); + } + else + { + P25CallEvent uuvcgeEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( uuvcge.getTransmitChannel() ) + .details( ( uuvcge.isEncrypted() ? "ENCRYPTED" : "" ) + + ( uuvcge.isEmergency() ? " EMERGENCY" : "") ) + .frequency( uuvcge.getDownlinkFrequency() ) + .from( uuvcge.getSourceWACN() + "-" + + uuvcge.getSourceSystemID() + "-" + + uuvcge.getSourceID() ) + .to( uuvcge.getTargetAddress() ) + .build(); + + addCall( uuvcgeEvent ); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: + if( pdu instanceof UnitToUnitVoiceChannelGrantUpdateExtended ) + { + UnitToUnitVoiceChannelGrantUpdateExtended uuvcgue = + (UnitToUnitVoiceChannelGrantUpdateExtended)pdu; + + if( isActiveCall( uuvcgue.getTransmitChannel(), + uuvcgue.getTargetAddress() ) ) + { + updateCall( State.CALL, + uuvcgue.getTransmitChannel(), + uuvcgue.getSourceAddress(), + uuvcgue.getTargetAddress() ); + } + else + { + P25CallEvent event = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( uuvcgue.getTransmitChannel() ) + .details( ( uuvcgue.isEncrypted() ? "ENCRYPTED" : "" ) + + ( uuvcgue.isEmergency() ? " EMERGENCY" : "") ) + .frequency( uuvcgue.getDownlinkFrequency() ) + .from( uuvcgue.getSourceWACN() + "-" + + uuvcgue.getSourceSystemID() + "-" + + uuvcgue.getSourceID() ) + .to( uuvcgue.getTargetAddress() ) + .build(); + + addCall( event ); + } + } + else + { + logAlternateVendorMessage( pdu ); + } + break; + default: + mLog.debug( "PDU - unrecognized OPCODE message: " + pdu.toString() ); + break; + } } } private void processTSBKCommand( TSBKMessage message ) { - CallEvent event = null; + P25CallEvent event = null; switch( message.getOpcode() ) { @@ -803,22 +2164,6 @@ public class P25ChannelState extends ChannelState mCallEventModel.add( event ); } - private void processMessage( PDUMessage message ) - { - MessageUpdateExtended mu = (MessageUpdateExtended)message; - - CallEvent event = - new P25CallEvent.Builder( CallEventType.SDM ) - .aliasList( mAliasList ) - .details( "MESSAGE: " + mu.getMessage() ) - .from( mu.getSourceWACN() + "-" + mu.getSourceSystemID() + - "-" + mu.getSourceID() ) - .to( mu.getTargetAddress() ) - .build(); - - mCallEventModel.add( event ); - } - private void processTSBKQuery( TSBKMessage message ) { CallEvent event = null; @@ -866,56 +2211,6 @@ public class P25ChannelState extends ChannelState } } - private void processQuery( PDUMessage message ) - { - CallEvent event = null; - - switch( message.getOpcode() ) - { - case GROUP_AFFILIATION_QUERY: - GroupAffiliationQueryExtended gaqe = - (GroupAffiliationQueryExtended)message; - - if( mLastQueryEventID == null || !gaqe.getTargetAddress() - .contentEquals( mLastQueryEventID ) ) - { - event = new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "GROUP AFFILIATION" ) - .from( gaqe.getWACN() + "-" + gaqe.getSystemID() + - "-" + gaqe.getSourceID() ) - .to( gaqe.getTargetAddress() ) - .build(); - } - break; - case STATUS_QUERY: - StatusQueryExtended sq = (StatusQueryExtended)message; - - if( mLastQueryEventID == null || !sq.getTargetAddress() - .contentEquals( mLastQueryEventID ) ) - { - event = new P25CallEvent.Builder( CallEventType.QUERY ) - .aliasList( mAliasList ) - .details( "STATUS QUERY" ) - .from( sq.getSourceWACN() + "-" + - sq.getSourceSystemID() + "-" + - sq.getSourceID() ) - .to( sq.getTargetAddress() ) - .build(); - } - break; - default: - break; - } - - if( event != null ) - { - mCallEventModel.add( event ); - - mLastQueryEventID = event.getToID(); - } - } - private void processTSBKResponse( TSBKMessage message ) { CallEvent event = null; @@ -1131,379 +2426,13 @@ public class P25ChannelState extends ChannelState } } - private void processResponse( PDUMessage message ) - { - CallEvent event = null; - - switch( message.getOpcode() ) - { - case GROUP_AFFILIATION_RESPONSE: - GroupAffiliationResponseExtended gar = - (GroupAffiliationResponseExtended)message; - - if( mLastResponseEventID == null || !gar.getTargetAddress() - .contentEquals( mLastResponseEventID ) ) - { - event = new P25CallEvent.Builder( CallEventType.RESPONSE ) - .aliasList( mAliasList ) - .details( "AFFILIATION:" + gar.getResponse().name() + - " FOR GROUP:" + gar.getGroupWACN() + "-" + - gar.getGroupSystemID() + "-" + - gar.getGroupID() + " ANNOUNCEMENT GROUP:" + - gar.getAnnouncementGroupID() ) - .from( gar.getSourceWACN() + "-" + - gar.getSourceSystemID() + "-" + - gar.getSourceID() ) - .to( gar.getTargetAddress() ) - .build(); - - mLastResponseEventID = gar.getTargetAddress(); - } - break; - case ROAMING_ADDRESS_UPDATE: - RoamingAddressUpdateExtended raue = - (RoamingAddressUpdateExtended)message; - - StringBuilder sb = new StringBuilder(); - sb.append( "ROAMING ADDRESS STACK A:" ); - sb.append( raue.getWACNA() + "-" + raue.getSystemIDA() ); - - if( raue.isFormat2() ) - { - sb.append( " B:" ); - sb.append( raue.getWACNB() + "-" + raue.getSystemIDB() ); - sb.append( " C:" ); - sb.append( raue.getWACNC() + "-" + raue.getSystemIDC() ); - sb.append( " D:" ); - sb.append( raue.getWACND() + "-" + raue.getSystemIDD() ); - } - - if( raue.isFormat3() ) - { - sb.append( " E:" ); - sb.append( raue.getWACNE() + "-" + raue.getSystemIDE() ); - sb.append( " F:" ); - sb.append( raue.getWACNF() + "-" + raue.getSystemIDF() ); - sb.append( " G:" ); - sb.append( raue.getWACNG() + "-" + raue.getSystemIDG() ); - } - - event = new P25CallEvent.Builder( CallEventType.RESPONSE ) - .aliasList( mAliasList ) - .details( sb.toString() ) - .from( raue.getSourceID() ) - .to( raue.getTargetAddress() ) - .build(); - break; - case STATUS_UPDATE: - StatusUpdateExtended su = (StatusUpdateExtended)message; - - if( mLastResponseEventID == null || !mLastResponseEventID - .contentEquals( su.getTargetAddress() ) ) - { - event = new P25CallEvent.Builder( CallEventType.RESPONSE ) - .aliasList( mAliasList ) - .details( "STATUS USER: " + su.getUserStatus() + - " UNIT: " + su.getUnitStatus() ) - .from( su.getSourceWACN() + "-" + - su.getSourceSystemID() + "-" + - su.getSourceID() ) - .to( su.getTargetAddress() ) - .build(); - - mLastResponseEventID = su.getTargetAddress(); - } - break; - case UNIT_REGISTRATION_RESPONSE: - UnitRegistrationResponseExtended urr = - (UnitRegistrationResponseExtended)message; - - if( urr.getResponse() == Response.ACCEPT ) - { - mRegistrations.put( urr.getAssignedSourceAddress(), - System.currentTimeMillis() ); - } - - if( mLastRegistrationEventID == null || !mLastRegistrationEventID - .contentEquals( urr.getAssignedSourceAddress() ) ) - { - event = new P25CallEvent.Builder( CallEventType.REGISTER ) - .aliasList( mAliasList ) - .details( "REGISTRATION:" + urr.getResponse().name() + - " FOR EXTERNAL SYSTEM ADDRESS: " + - urr.getWACN() + "-" + - urr.getSystemID() + "-" + - urr.getSourceAddress() + - " SOURCE ID: " + urr.getSourceID() ) - .from( urr.getAssignedSourceAddress() ) - .build(); - - mLastRegistrationEventID = urr.getAssignedSourceAddress(); - } - break; - default: - break; - } - - if( event != null ) - { - mCallEventModel.add( event ); - } - } - private void processTSBKRFSSStatus( RFSSStatusBroadcast message ) { - if( mNAC == null || !mNAC.contentEquals( message.getNAC() ) ) - { - mNAC = message.getNAC(); - - broadcastChange( ChangedAttribute.NAC ); - } + updateNAC( message.getNAC() ); - if( mSystem == null || !mSystem.contentEquals( message.getSystemID() ) ) - { - mSystem = message.getSystemID(); - - broadcastChange( ChangedAttribute.SYSTEM ); - } - - String site = message.getRFSubsystemID() + "-" + message.getSiteID(); - - if( mSite == null || !mSite.contentEquals( site ) ) - { - mSite = site; - - broadcastChange( ChangedAttribute.SITE ); - } - } - - private void processRFSSStatus( RFSSStatusBroadcastExtended message ) - { - if( mNAC == null || !mNAC.contentEquals( message.getNAC() ) ) - { - mNAC = message.getNAC(); - - broadcastChange( ChangedAttribute.NAC ); - } - - if( mSystem == null || !mSystem.contentEquals( message.getSystemID() ) ) - { - mSystem = message.getSystemID(); - - broadcastChange( ChangedAttribute.SYSTEM ); - } - - String site = message.getRFSubsystemID() + "-" + message.getSiteID(); - - if( mSite == null || !mSite.contentEquals( site ) ) - { - mSite = site; - - if( mAliasList != null ) - { - Alias alias = mAliasList.getSiteID( mSite ); - - if( alias != null ) - { - mSiteAlias = alias.getName(); - } - else - { - mSiteAlias = null; - } - } - - broadcastChange( ChangedAttribute.SITE ); - - broadcastChange( ChangedAttribute.SITE_ALIAS ); - } - } - - private void processPDUCall( PDUMessage message ) - { - switch( message.getOpcode() ) - { - case CALL_ALERT: - CallAlertExtended ca = (CallAlertExtended)message; - - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.PAGE ) - .aliasList( mAliasList ) - .from( ca.getWACN() + "-" + ca.getSystemID() + "-" + - ca.getSourceID() ) - .to( ca.getTargetAddress() ) - .build() ); - break; - case GROUP_DATA_CHANNEL_GRANT: - GroupDataChannelGrantExtended gdcge = - (GroupDataChannelGrantExtended)message; - - if( isActiveCall( gdcge.getTransmitChannel(), gdcge.getGroupAddress() ) ) - { - updateCall( gdcge.getTransmitChannel(), null, gdcge.getGroupAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.DATA_CALL ) - .aliasList( mAliasList ) - .channel( gdcge.getTransmitChannel() ) - .details( ( gdcge.isEncrypted() ? "ENCRYPTED" : "" ) + - ( gdcge.isEmergency() ? " EMERGENCY" : "") ) - .frequency( gdcge.getDownlinkFrequency() ) - .from( gdcge.getSourceAddress() ) - .to( gdcge.getGroupAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - break; - case GROUP_VOICE_CHANNEL_GRANT: - GroupVoiceChannelGrantExplicit gvcge = - (GroupVoiceChannelGrantExplicit)message; - - if( isActiveCall( gvcge.getTransmitChannel(), gvcge.getGroupAddress() ) ) - { - updateCall( gvcge.getTransmitChannel(), null, gvcge.getGroupAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.CALL ) - .aliasList( mAliasList ) - .channel( gvcge.getTransmitChannel() ) - .details( ( gvcge.isEncrypted() ? "ENCRYPTED" : "" ) + - ( gvcge.isEmergency() ? " EMERGENCY" : "") ) - .frequency( gvcge.getDownlinkFrequency() ) - .from( gvcge.getSourceAddress() ) - .to( gvcge.getGroupAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - break; - case INDIVIDUAL_DATA_CHANNEL_GRANT: - IndividualDataChannelGrantExtended idcge = - (IndividualDataChannelGrantExtended)message; - - if( isActiveCall( idcge.getTransmitChannel(), idcge.getTargetAddress() ) ) - { - updateCall( idcge.getTransmitChannel(), null, idcge.getTargetAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.DATA_CALL ) - .aliasList( mAliasList ) - .channel( idcge.getTransmitChannel() ) - .details( ( idcge.isEncrypted() ? "ENCRYPTED" : "" ) + - ( idcge.isEmergency() ? " EMERGENCY" : "") ) - .frequency( idcge.getDownlinkFrequency() ) - .from( idcge.getSourceWACN() + "-" + - idcge.getSourceSystemID() + "-" + - idcge.getSourceAddress() ) - .to( idcge.getTargetAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - break; - case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: - TelephoneInterconnectChannelGrantExplicit ticge = - (TelephoneInterconnectChannelGrantExplicit)message; - - if( isActiveCall( ticge.getTransmitChannel(), ticge.getAddress() )) - { - updateCall( ticge.getTransmitChannel(), null, ticge.getAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.TELEPHONE_CALL ) - .aliasList( mAliasList ) - .channel( ticge.getTransmitChannel() ) - .details( ( ticge.isEncrypted() ? "ENCRYPTED" : "" ) + - ( ticge.isEmergency() ? " EMERGENCY" : "") + - " CALL TIMER:" + ticge.getCallTimer() ) - .frequency( ticge.getDownlinkFrequency() ) - .from( ticge.getAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - break; - case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: - UnitToUnitVoiceChannelGrantExtended uuvcge = - (UnitToUnitVoiceChannelGrantExtended)message; - - if( isActiveCall( uuvcge.getTransmitChannel(), uuvcge.getTargetAddress() ) ) - { - updateCall( uuvcge.getTransmitChannel(), null, uuvcge.getTargetAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.CALL ) - .aliasList( mAliasList ) - .channel( uuvcge.getTransmitChannel() ) - .details( ( uuvcge.isEncrypted() ? "ENCRYPTED" : "" ) + - ( uuvcge.isEmergency() ? " EMERGENCY" : "") ) - .frequency( uuvcge.getDownlinkFrequency() ) - .from( uuvcge.getSourceWACN() + "-" + - uuvcge.getSourceSystemID() + "-" + - uuvcge.getSourceID() ) - .to( uuvcge.getTargetAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - break; - case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: - UnitToUnitVoiceChannelGrantUpdateExtended uuvcgue = - (UnitToUnitVoiceChannelGrantUpdateExtended)message; - - if( isActiveCall( uuvcgue.getTransmitChannel(), - uuvcgue.getTargetAddress() ) ) - { - updateCall( uuvcgue.getTransmitChannel(), null, - uuvcgue.getTargetAddress() ); - } - else - { - CallEvent event = - new P25CallEvent.Builder( CallEventType.CALL ) - .aliasList( mAliasList ) - .channel( uuvcgue.getTransmitChannel() ) - .details( ( uuvcgue.isEncrypted() ? "ENCRYPTED" : "" ) + - ( uuvcgue.isEmergency() ? " EMERGENCY" : "") ) - .frequency( uuvcgue.getDownlinkFrequency() ) - .from( uuvcgue.getSourceWACN() + "-" + - uuvcgue.getSourceSystemID() + "-" + - uuvcgue.getSourceID() ) - .to( uuvcgue.getTargetAddress() ) - .build(); - - mCallEventModel.add( event ); - - addCall( event ); - } - - break; - - default: - break; - } + updateSystem( message.getSystemID() ); + updateSite( message.getRFSubsystemID() + "-" + message.getSiteID() ); } /** @@ -1528,11 +2457,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdca.getChannel1(), gdca.getGroupAddress1() ) ) { - updateCall( gdca.getChannel1(), null, gdca.getGroupAddress1() ); + updateCall( State.DATA, + gdca.getChannel1(), + gdca.getGroupAddress2(), + gdca.getGroupAddress1() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( gdca.getChannel1() ) @@ -1551,11 +2483,14 @@ public class P25ChannelState extends ChannelState { if( isActiveCall( gdca.getChannel2(), gdca.getGroupAddress2() ) ) { - updateCall( gdca.getChannel2(), null, gdca.getGroupAddress2() ); + updateCall( State.DATA, + gdca.getChannel2(), + null, + gdca.getGroupAddress2() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( gdca.getChannel2() ) @@ -1577,11 +2512,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdcae.getTransmitChannel(), gdcae.getGroupAddress() ) ) { - updateCall( gdcae.getTransmitChannel(), null, gdcae.getGroupAddress() ); + updateCall( State.DATA, + gdcae.getTransmitChannel(), + null, + gdcae.getGroupAddress() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( gdcae.getTransmitChannel() ) @@ -1601,11 +2539,13 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdcg.getChannel(), gdcg.getGroupAddress() ) ) { - updateCall( gdcg.getChannel(), null, gdcg.getGroupAddress() ); + updateCall( State.DATA, + gdcg.getChannel(), null, + gdcg.getGroupAddress() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( gdcg.getChannel() ) @@ -1626,11 +2566,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gvcg.getChannel(), gvcg.getGroupAddress() ) ) { - updateCall( gvcg.getChannel(), null, gvcg.getGroupAddress() ); + updateCall( State.CALL, + gvcg.getChannel(), + gvcg.getSourceAddress(), + gvcg.getGroupAddress() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) .channel( gvcg.getChannel() ) @@ -1652,11 +2595,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gvcgu.getChannel1(), gvcgu.getGroupAddress1() ) ) { - updateCall( gvcgu.getChannel1(), null, gvcgu.getGroupAddress1() ); + updateCall( State.CALL, + gvcgu.getChannel1(), + gvcgu.getGroupAddress2(), + gvcgu.getGroupAddress1() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) .channel( gvcgu.getChannel1() ) @@ -1675,11 +2621,13 @@ public class P25ChannelState extends ChannelState { if( isActiveCall( gvcgu.getChannel2(), gvcgu.getGroupAddress2() ) ) { - updateCall( gvcgu.getChannel2(), null, gvcgu.getGroupAddress2() ); + updateCall( State.CALL, + gvcgu.getChannel2(), null, + gvcgu.getGroupAddress2() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) .channel( gvcgu.getChannel2() ) @@ -1715,11 +2663,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( idcg.getChannel(), idcg.getTargetAddress() ) ) { - updateCall( idcg.getChannel(), null, idcg.getTargetAddress() ); + updateCall( State.DATA, + idcg.getChannel(), + idcg.getSourceAddress(), + idcg.getTargetAddress() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( idcg.getChannel() ) @@ -1740,11 +2691,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( sdcg.getTransmitChannel(), sdcg.getTargetAddress() ) ) { - updateCall( sdcg.getTransmitChannel(), null, sdcg.getTargetAddress() ); + updateCall( State.DATA, + sdcg.getTransmitChannel(), + null, + sdcg.getTargetAddress() ); } else { - CallEvent event = + P25CallEvent event = new P25CallEvent.Builder( CallEventType.DATA_CALL ) .aliasList( mAliasList ) .channel( sdcg.getTransmitChannel() ) @@ -1764,11 +2718,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( tivcg.getChannel(), tivcg.getAddress() )) { - updateCall( tivcg.getChannel(), null, tivcg.getAddress() ); + updateCall( State.CALL, + tivcg.getChannel(), + tivcg.getSourceAddress(), + tivcg.getAddress() ); } else { - CallEvent tivcgEvent = + P25CallEvent tivcgEvent = new P25CallEvent.Builder( CallEventType.TELEPHONE_CALL ) .aliasList( mAliasList ) .channel( tivcg.getChannel() ) @@ -1790,11 +2747,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( tivcgu.getChannel(), tivcgu.getAddress() ) ) { - updateCall( tivcgu.getChannel(), null, tivcgu.getAddress() ); + updateCall( State.CALL, + tivcgu.getChannel(), + tivcgu.getSourceAddress(), + tivcgu.getAddress() ); } else { - CallEvent tivcguEvent = + P25CallEvent tivcguEvent = new P25CallEvent.Builder( CallEventType.TELEPHONE_CALL ) .aliasList( mAliasList ) .channel( tivcgu.getChannelIdentifier() + "-" + @@ -1816,11 +2776,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcg.getChannel(), uuvcg.getTargetAddress() ) ) { - updateCall( uuvcg.getChannel(), null, uuvcg.getTargetAddress() ); + updateCall( State.CALL, + uuvcg.getChannel(), + uuvcg.getSourceAddress(), + uuvcg.getTargetAddress() ); } else { - CallEvent uuvcgEvent = + P25CallEvent uuvcgEvent = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) .channel( uuvcg.getChannelIdentifier() + "-" + @@ -1844,11 +2807,14 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcgu.getChannel(), uuvcgu.getTargetAddress() ) ) { - updateCall( uuvcgu.getChannel(), null, uuvcgu.getTargetAddress() ); + updateCall( State.CALL, + uuvcgu.getChannel(), + uuvcgu.getSourceAddress(), + uuvcgu.getTargetAddress() ); } else { - CallEvent uuvcguEvent = + P25CallEvent uuvcguEvent = new P25CallEvent.Builder( CallEventType.CALL ) .aliasList( mAliasList ) .channel( uuvcgu.getChannelIdentifier() + "-" + @@ -1871,52 +2837,299 @@ public class P25ChannelState extends ChannelState } } - private boolean isActiveCall( String channel, String id ) + /** + * Indicates if either the current call, or any current call detects contain + * the talkgroup id. For the current call, only the TO talkgroup is tested + * + * @param channel + * @param talkgroup + * @return + */ + private boolean isActiveCall( String channel, String talkgroup ) { - for( ActiveCall call: mActiveCalls ) + if( channel != null ) { - if( call.matches( channel, id ) ) + if( mCurrentChannel.contentEquals( channel ) ) { - return true; + return mCurrentActiveCall != null && + ( talkgroup == null || + mCurrentActiveCall.getCallEvent().getToID().contentEquals( talkgroup ) ); + } + else + { + ActiveCall call = mCallDetects.get( channel ); + + if( call != null ) + { + return talkgroup != null && call.getTalkgroups().contains( talkgroup ); + } } } return false; } - - private void addCall( CallEvent event ) + + /** + * Starts a new call event. For P25 Phase 1, only 1 call event should ever + * have a call event type of CALL. All other detected call events on other + * channels should use call event type CALL DETECT. + */ + private void addCall( P25CallEvent event ) { - mActiveCalls.add( new ActiveCall( getProcessingChain() - .getResourceManager().getThreadPoolManager(), event ) ); + mCallEventModel.add( event ); + + String channel = event.getChannel(); + + ActiveCall call = new ActiveCall( getProcessingChain() + .getResourceManager().getThreadPoolManager(), event ); + + if( channel.contentEquals( mCurrentChannel ) ) + { + if( mCurrentActiveCall != null ) + { + mCurrentActiveCall.end(); + } + + mCurrentActiveCall = call; + + switch( event.getCallEventType() ) + { + case CALL: + setState( State.CALL ); + updateFrom( event.getFromID() ); + updateTo( event.getToID() ); + break; + case DATA_CALL: + setState( State.DATA ); + updateFrom( event.getFromID() ); + updateTo( event.getToID() ); + break; + case CALL_DETECT: + /* don't update call state */ + default: + break; + } + } + else + { + /* End the current channel call event, if there is one */ + if( mCallDetects.containsKey( channel ) ) + { + mCallDetects.get( channel ).end(); + } + + mCallDetects.put( channel, call ); + } + } - private void updateCall( String channel, String fromID, String toID ) + /** + * Ends all calls in the mActiveCalls queue + */ + private void endAllCalls() { - for( ActiveCall call: mActiveCalls ) + if( mCurrentActiveCall != null ) { - if( call.matches( channel, toID ) ) + mCurrentActiveCall.end(); + } + + for( ActiveCall call: mCallDetects.values() ) + { + call.end(); + } + } + + /** + * Updates state, channel, from and to for a currently active call. Use the + * isActiveCall() method to verify that a call is currently active, otherwise + * this invocation is ignored + */ + private void updateCall( State state, + String channel, + String from, + String to ) + { + if( mCurrentChannel.contentEquals( channel ) ) + { + if( mCurrentActiveCall != null ) { - call.update( System.currentTimeMillis() ); + mCurrentActiveCall.update(); + + P25CallEvent event = mCurrentActiveCall.getCallEvent(); - setState( getState() ); - - if( fromID != null && - !call.getCallEvent().getFromID().contentEquals( fromID ) ) + switch( event.getCallEventType() ) { - call.getCallEvent().setFromID( fromID ); + case CALL: + setState( State.CALL ); + + /* Broacast call state update */ + updateFrom( from ); + updateTo( to ); + + if( from != null && + !from.contentEquals( "0000" ) && + !from.contentEquals( "000000" ) && + ( !event.hasFromID() || !event.getFromID().contentEquals( from ) ) ) + { + event.setFromID( from ); + } + break; + case DATA_CALL: + setState( State.DATA ); + + updateFrom( from ); + updateTo( to ); + + if( from != null && + !from.contentEquals( "0000" ) && + !from.contentEquals( "000000" ) && + ( !event.hasFromID() || !event.getFromID().contentEquals( from ) ) ) + { + event.setFromID( from ); + } + break; + case CALL_DETECT: + /* don't update call state */ + default: + break; } - - return; + } + else + { + mLog.debug( "Request to update non-existent current call with " + + "state:" + state + " channel:" + channel + " from:" + + from + " to:" + to ); + } + } + else + { + ActiveCall call = mCallDetects.get( channel ); + + if( call != null ) + { + /* Update the timestamp to now */ + call.update(); + } + else + { + mLog.debug( "Request to update non-existent call detect with " + + "state:" + state + " channel:" + channel + " from:" + + from + " to:" + to ); } } } + + /** + * Broadcasts an update for the TO group or unit address + */ + private void updateTo( String to ) + { + if( to != null && + !to.contentEquals( "0000" ) && + !to.contentEquals( "000000" ) && + ( mToTalkgroup == null || !mToTalkgroup.contentEquals( to ) ) ) + { + mToTalkgroup = to; + broadcastChange( ChangedAttribute.TO_TALKGROUP ); + + if( mAliasList != null ) + { + Alias toAlias = mAliasList.getTalkgroupAlias( to ); + + if( toAlias != null ) + { + mToAlias = toAlias.getName(); + broadcastChange( ChangedAttribute.TO_TALKGROUP_ALIAS ); + } + } + } + } + + /** + * Broadcasts an update for the FROM group or unit address + */ + private void updateFrom( String from ) + { + if( from != null && + !from.contentEquals( "0000" ) && + !from.contentEquals( "000000" ) && + ( mFromTalkgroup == null || !mFromTalkgroup.contentEquals( from ) ) ) + { + mFromTalkgroup = from; + broadcastChange( ChangedAttribute.FROM_TALKGROUP ); + + if( mAliasList != null ) + { + Alias toAlias = mAliasList.getTalkgroupAlias( from ); + + if( toAlias != null ) + { + mFromAlias = toAlias.getName(); + broadcastChange( ChangedAttribute.FROM_TALKGROUP_ALIAS ); + } + } + } + } + + /** + * Broadcasts an update to the NAC + */ + private void updateNAC( String nac ) + { + if( mNAC == null && nac != null ) + { + mNAC = nac; + + broadcastChange( ChangedAttribute.NAC ); + } + } + + /** + * Updates the site information + */ + private void updateSite( String site ) + { + if( mSite == null || !mSite.contentEquals( site ) ) + { + mSite = site; + + broadcastChange( ChangedAttribute.SITE ); + + if( mAliasList != null ) + { + Alias alias = mAliasList.getSiteID( mSite ); + + if( alias != null ) + { + mSiteAlias = alias.getName(); + } + else + { + mSiteAlias = null; + } + } + + broadcastChange( ChangedAttribute.SITE_ALIAS ); + } + } + + private void updateSystem( String system ) + { + if( mSystem == null || !mSystem.contentEquals( system ) ) + { + mSystem = system; + + broadcastChange( ChangedAttribute.SYSTEM ); + } + } + /** * Process a unit paging event message */ private void processTSBKPage( TSBKMessage message ) { - CallEvent event = null; + P25CallEvent event = null; switch( message.getOpcode() ) { @@ -1980,31 +3193,6 @@ public class P25ChannelState extends ChannelState } } - private void processPage( PDUMessage message ) - { - if( message.getOpcode() == Opcode.UNIT_TO_UNIT_ANSWER_REQUEST ) - { - UnitToUnitAnswerRequestExplicit utuare = - (UnitToUnitAnswerRequestExplicit)message; - - if( mLastPageEventID == null || !mLastPageEventID - .contentEquals( utuare.getTargetAddress() ) ) - { - mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.PAGE ) - .aliasList( mAliasList ) - .details( ( utuare.isEmergency() ? "EMERGENCY" : "" ) ) - .from( utuare.getWACN() + "-" + - utuare.getSystemID() + "-" + - utuare.getSourceID() ) - .to( utuare.getTargetAddress() ) - .build() ); - - mLastPageEventID = utuare.getTargetAddress(); - } - } - } - @Override public String getActivitySummary() { @@ -2063,34 +3251,63 @@ public class P25ChannelState extends ChannelState public class ActiveCall { - public static final long TIMEOUT = 2000; //milliseconds + public static final long CALL_TIMEOUT = 2000; //milliseconds + public static final long CALL_DETECT_TIMEOUT = 5000; //milliseconds - private CallEvent mEvent; + private P25CallEvent mEvent; private long mLastUpdate; private ThreadPoolManager mThreadPoolManager; + private AtomicBoolean mEnded = new AtomicBoolean( false ); + private long mTimeout; + private List mTalkgroups = new ArrayList(); - public ActiveCall( ThreadPoolManager threadManager, CallEvent event ) + public ActiveCall( ThreadPoolManager threadManager, P25CallEvent event ) { mThreadPoolManager = threadManager; mEvent = event; + + if( event.getFromID() != null ) + { + mTalkgroups.add( event.getFromID() ); + } + + if( event.getToID() != null ) + { + mTalkgroups.add( event.getToID() ); + } + mLastUpdate = System.currentTimeMillis(); + + mTimeout = event.getCallEventType() == + CallEventType.CALL_DETECT ? CALL_DETECT_TIMEOUT : CALL_TIMEOUT; mThreadPoolManager.scheduleOnce( new CallExpirationCheck( this ), - TIMEOUT, TimeUnit.MILLISECONDS ); + mTimeout, TimeUnit.MILLISECONDS ); } - public CallEvent getCallEvent() + public P25CallEvent getCallEvent() { return mEvent; } + public List getTalkgroups() + { + return mTalkgroups; + } + public boolean matches( String channel, String id ) { - return mEvent.getChannel().contentEquals( channel ) && + return mEvent.getChannel() != null && + channel != null && + mEvent.getChannel().contentEquals( channel ) && + id != null && mEvent.getToID().contentEquals( id ); } - public void update( long timestamp ) + /** + * Sets the last update timestamp to now + */ + public void update() { mLastUpdate = System.currentTimeMillis(); } @@ -2098,21 +3315,46 @@ public class P25ChannelState extends ChannelState public void checkExpiration() { long now = System.currentTimeMillis(); - - if( now > mLastUpdate + TIMEOUT ) + + if( !mEnded.get() ) { - mCallEventModel.setEnd( mEvent ); - mActiveCalls.remove( this ); - -// if( mEvent.getChannel().contentEquals( CURRENT_CHANNEL ) ) -// { -// setState( State.IDLE ); -// } + if( now > mLastUpdate + mTimeout ) + { + cleanup(); + } + else + { + mThreadPoolManager.scheduleOnce( new CallExpirationCheck( this ), + mTimeout, TimeUnit.MILLISECONDS ); + } + } + } + + public void end() + { + /* The expire check timer could fire while we're doing this, so we + * need to safely switch the flag and then run cleanup */ + if( mEnded.compareAndSet( false, true ) ) + { + cleanup(); + } + } + + private void cleanup() + { + setState( State.FADE ); + mCallEventModel.setEnd( mEvent ); + + if( mEvent.getChannel().contentEquals( mCurrentChannel ) ) + { + if( mCurrentActiveCall == this ) + { + mCurrentActiveCall = null; + } } else { - mThreadPoolManager.scheduleOnce( new CallExpirationCheck( this ), - TIMEOUT, TimeUnit.MILLISECONDS ); + mCallDetects.remove( this ); } } diff --git a/src/decode/p25/P25MessageProcessor.java b/src/decode/p25/P25MessageProcessor.java index 82bf3d01..91c6427d 100644 --- a/src/decode/p25/P25MessageProcessor.java +++ b/src/decode/p25/P25MessageProcessor.java @@ -10,8 +10,8 @@ import org.slf4j.LoggerFactory; import sample.Broadcaster; import sample.Listener; import alias.AliasList; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; -import decode.p25.message.tsbk.osp.control.IdentifierUpdate; public class P25MessageProcessor implements Listener { @@ -23,8 +23,8 @@ public class P25MessageProcessor implements Listener /* Map of up to 16 band identifiers per RFSS. These identifier update * messages are inserted into any message that conveys channel information * so that the uplink/downlink frequencies can be calculated */ - private HashMap mIdentifierMap = - new HashMap(); + private HashMap mBandIdentifierMap = + new HashMap(); private AliasList mAliasList; @@ -48,17 +48,18 @@ public class P25MessageProcessor implements Listener for( int identifier: identifiers ) { receiver.setIdentifierMessage( identifier, - mIdentifierMap.get( identifier ) ); + mBandIdentifierMap.get( identifier ) ); } } /* Store band identifiers so that they can be injected into channel * type messages */ - if( message instanceof IdentifierUpdate ) + if( message instanceof IBandIdentifier ) { - IdentifierUpdate identifierUpdate = (IdentifierUpdate)message; + IBandIdentifier bandIdentifier = (IBandIdentifier)message; - mIdentifierMap.put( identifierUpdate.getIdentifier(), identifierUpdate ); + mBandIdentifierMap.put( bandIdentifier.getIdentifier(), + bandIdentifier ); } mBroadcaster.broadcast( message ); @@ -67,7 +68,7 @@ public class P25MessageProcessor implements Listener public void dispose() { - mIdentifierMap.clear(); + mBandIdentifierMap.clear(); mBroadcaster.dispose(); } diff --git a/src/decode/p25/P25Panel.java b/src/decode/p25/P25Panel.java index c4f2e254..fb1010aa 100644 --- a/src/decode/p25/P25Panel.java +++ b/src/decode/p25/P25Panel.java @@ -25,6 +25,7 @@ import settings.ColorSetting; import settings.Setting; import controller.channel.Channel; import controller.state.ChannelState.ChangedAttribute; +import controller.state.ChannelState.State; import controller.state.ChannelStatePanel; import decode.config.DecodeConfigP25Phase1; @@ -86,7 +87,7 @@ public class P25Panel extends ChannelStatePanel mFromAlias.setFont( mFontDecoder ); mFromAlias.setForeground( mColorLabelDecoder ); - mNAC.setFont( mFontDecoder ); + mNAC.setFont( mFontDetails ); mNAC.setForeground( mColorLabelDecoder ); mTo.setFont( mFontDecoder ); @@ -95,13 +96,13 @@ public class P25Panel extends ChannelStatePanel mToAlias.setFont( mFontDecoder ); mToAlias.setForeground( mColorLabelDecoder ); - mSystem.setFont( mFontDecoder ); + mSystem.setFont( mFontDetails ); mSystem.setForeground( mColorLabelDecoder ); mSiteAlias.setFont( mFontDecoder ); mSiteAlias.setForeground( mColorLabelDecoder ); - mSite.setFont( mFontDecoder ); + mSite.setFont( mFontDetails ); mSite.setForeground( mColorLabelDecoder ); add( mStateLabel ); @@ -135,7 +136,17 @@ public class P25Panel extends ChannelStatePanel switch( changedAttribute ) { case CHANNEL_STATE: - mStateLabel.setText( channelState.getState().getDisplayValue() ); + State state = channelState.getState(); + + mStateLabel.setText( state.getDisplayValue() ); + + if( state == State.IDLE ) + { + mFrom.setText( null ); + mFromAlias.setText( null ); + mTo.setText( null ); + mToAlias.setText( null ); + } break; case SOURCE: mSourceLabel.setText( mChannel.getSourceConfiguration() diff --git a/src/decode/p25/message/IdentifierProvider.java b/src/decode/p25/message/IBandIdentifier.java similarity index 92% rename from src/decode/p25/message/IdentifierProvider.java rename to src/decode/p25/message/IBandIdentifier.java index f61b15d6..ad995510 100644 --- a/src/decode/p25/message/IdentifierProvider.java +++ b/src/decode/p25/message/IBandIdentifier.java @@ -1,6 +1,6 @@ package decode.p25.message; -public interface IdentifierProvider +public interface IBandIdentifier { /** diff --git a/src/decode/p25/message/IdentifierReceiver.java b/src/decode/p25/message/IdentifierReceiver.java index aa203018..0438ae1b 100644 --- a/src/decode/p25/message/IdentifierReceiver.java +++ b/src/decode/p25/message/IdentifierReceiver.java @@ -8,7 +8,7 @@ package decode.p25.message; */ public interface IdentifierReceiver { - public void setIdentifierMessage( int identifier, IdentifierProvider message ); + public void setIdentifierMessage( int identifier, IBandIdentifier message ); public int[] getIdentifiers(); } diff --git a/src/decode/p25/message/P25Message.java b/src/decode/p25/message/P25Message.java index f552165b..69f20486 100644 --- a/src/decode/p25/message/P25Message.java +++ b/src/decode/p25/message/P25Message.java @@ -179,7 +179,7 @@ public class P25Message extends Message * @param channel - channel number * @return - frequency in Hertz */ - protected static long calculateUplink( IdentifierProvider iden, int channel ) + protected static long calculateUplink( IBandIdentifier iden, int channel ) { long downlink = calculateDownlink( iden, channel ); @@ -199,7 +199,7 @@ public class P25Message extends Message * @param channel - channel number * @return - frequency in Hertz */ - protected static long calculateDownlink( IdentifierProvider iden, int channel ) + protected static long calculateDownlink( IBandIdentifier iden, int channel ) { if( iden != null ) { diff --git a/src/decode/p25/message/hdu/HDUMessage.java b/src/decode/p25/message/hdu/HDUMessage.java index 3b0114a7..cd3f5f45 100644 --- a/src/decode/p25/message/hdu/HDUMessage.java +++ b/src/decode/p25/message/hdu/HDUMessage.java @@ -1,5 +1,6 @@ package decode.p25.message.hdu; +import alias.Alias; import alias.AliasList; import bits.BinaryMessage; import decode.p25.message.P25Message; @@ -58,7 +59,16 @@ public class HDUMessage extends P25Message if( encryption != Encryption.UNENCRYPTED ) { sb.append( " ENCRYPTION:" ); - sb.append( encryption.name() ); + + if( encryption == Encryption.UNKNOWN ) + { + sb.append( "UNK ALGO ID:" ); + sb.append( mMessage.getInt( ALGORITHM_ID ) ); + } + else + { + sb.append( encryption.name() ); + } sb.append( " KEY ID:" + getKeyID() ); sb.append( " MSG INDICATOR:" + getMessageIndicator() ); } @@ -98,6 +108,12 @@ public class HDUMessage extends P25Message return mMessage.getHex( TALKGROUP_ID, 4 ); } + @Override + public String getToID() + { + return getTalkgroupID(); + } + /* Temporary override */ public boolean isValid() { diff --git a/src/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java b/src/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java index ad5ff94a..9e2d49f2 100644 --- a/src/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java +++ b/src/decode/p25/message/ldu/lc/AdjacentSiteStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; @@ -26,7 +26,7 @@ public class AdjacentSiteStatusBroadcast extends LDU1Message public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, 754,755 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public AdjacentSiteStatusBroadcast( LDU1Message message ) { @@ -100,7 +100,7 @@ public class AdjacentSiteStatusBroadcast extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java b/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java index 457a3dba..1adf1b34 100644 --- a/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java +++ b/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdate.java @@ -3,12 +3,12 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; public class ChannelIdentifierUpdate extends LDU1Message - implements IdentifierProvider + implements IBandIdentifier { private final static Logger mLog = LoggerFactory.getLogger( ChannelIdentifierUpdate.class ); diff --git a/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java b/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java index 53321bbb..18ebe8a6 100644 --- a/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java +++ b/src/decode/p25/message/ldu/lc/ChannelIdentifierUpdateExplicit.java @@ -3,12 +3,12 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; public class ChannelIdentifierUpdateExplicit extends LDU1Message - implements IdentifierProvider + implements IBandIdentifier { private final static Logger mLog = LoggerFactory.getLogger( ChannelIdentifierUpdateExplicit.class ); diff --git a/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java b/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java index 89685506..c4670f49 100644 --- a/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java +++ b/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdate.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; @@ -25,8 +25,8 @@ public class GroupVoiceChannelUpdate extends LDU1Message public static final int[] GROUP_ADDRESS_B = { 732,733,734,735,740,741,742, 743,744,745,750,751,752,753,754,755 }; - private IdentifierProvider mIdentifierUpdateA; - private IdentifierProvider mIdentifierUpdateB; + private IBandIdentifier mIdentifierUpdateA; + private IBandIdentifier mIdentifierUpdateB; public GroupVoiceChannelUpdate( LDU1Message message ) { @@ -106,7 +106,7 @@ public class GroupVoiceChannelUpdate extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getChannelIdentifierA() ) { diff --git a/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java b/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java index eb5470ba..c9555ba3 100644 --- a/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java +++ b/src/decode/p25/message/ldu/lc/GroupVoiceChannelUpdateExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.P25Message.DuplexMode; import decode.p25.message.P25Message.SessionMode; @@ -29,8 +29,8 @@ public class GroupVoiceChannelUpdateExplicit extends LDU1Message public static final int[] RECEIVE_CHANNEL = { 740,741,742,743,744,745,750, 751,752,753,754,755 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public GroupVoiceChannelUpdateExplicit( LDU1Message message ) { @@ -120,7 +120,7 @@ public class GroupVoiceChannelUpdateExplicit extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java b/src/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java index 7a6b77c6..0e4ab8a8 100644 --- a/src/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java +++ b/src/decode/p25/message/ldu/lc/NetworkStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; @@ -24,7 +24,7 @@ public class NetworkStatusBroadcast extends LDU1Message public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, 754,755 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public NetworkStatusBroadcast( LDU1Message source ) { @@ -45,7 +45,7 @@ public class NetworkStatusBroadcast extends LDU1Message sb.append( getMessageStub() ); sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); + sb.append( " SYS:" + getSystem() ); sb.append( " CHAN:" + getChannel() ); sb.append( " " + Service.getServices( getSystemServiceClass() ).toString() ); @@ -57,7 +57,7 @@ public class NetworkStatusBroadcast extends LDU1Message return mMessage.getHex( NETWORK_ID, 5 ); } - public String getSystemID() + public String getSystem() { return mMessage.getHex( SYSTEM_ID, 3 ); } @@ -83,7 +83,7 @@ public class NetworkStatusBroadcast extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java b/src/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java index 8012e815..cbc6f51a 100644 --- a/src/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java +++ b/src/decode/p25/message/ldu/lc/NetworkStatusBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.reference.LinkControlOpcode; @@ -24,8 +24,8 @@ public class NetworkStatusBroadcastExplicit extends LDU1Message public static final int[] RECEIVE_CHANNEL = { 740,741,742,743,744,745,750, 751,752,753,754,755 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public NetworkStatusBroadcastExplicit( LDU1Message message ) { @@ -46,7 +46,7 @@ public class NetworkStatusBroadcastExplicit extends LDU1Message sb.append( getMessageStub() ); sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); + sb.append( " SYS:" + getSystem() ); sb.append( " TRANSMIT:" + getTransmitChannel() ); sb.append( " RECEIVE:" + getReceiveChannel() ); @@ -58,7 +58,7 @@ public class NetworkStatusBroadcastExplicit extends LDU1Message return mMessage.getHex( NETWORK_ID, 5 ); } - public String getSystemID() + public String getSystem() { return mMessage.getHex( SYSTEM_ID, 3 ); } @@ -94,7 +94,7 @@ public class NetworkStatusBroadcastExplicit extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java b/src/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java index 0553f6a7..501a2c86 100644 --- a/src/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java +++ b/src/decode/p25/message/ldu/lc/RFSSStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.message.tsbk.osp.control.SystemService; @@ -26,7 +26,7 @@ public class RFSSStatusBroadcast extends LDU1Message public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753, 754,755 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public RFSSStatusBroadcast( LDU1Message message ) { @@ -102,7 +102,7 @@ public class RFSSStatusBroadcast extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java b/src/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java index cb2fec68..e49a363c 100644 --- a/src/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java +++ b/src/decode/p25/message/ldu/lc/RFSSStatusBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.message.tsbk.osp.control.SystemService; @@ -26,8 +26,8 @@ public class RFSSStatusBroadcastExplicit extends LDU1Message 735,740,741,742,743 }; public static final int[] SYSTEM_SERVICE_CLASS = { 744,745,750,751,752,753,754,755 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public RFSSStatusBroadcastExplicit( LDU1Message source ) { @@ -113,7 +113,7 @@ public class RFSSStatusBroadcastExplicit extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java b/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java index ad73d5a8..81342a55 100644 --- a/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java +++ b/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.message.tsbk.osp.control.SystemService; @@ -26,8 +26,8 @@ public class SecondaryControlChannelBroadcast extends LDU1Message 741,742,743 }; public static final int[] SYSTEM_SERVICE_CLASS_B = { 744,745,750,751,752,753,754,755 }; - private IdentifierProvider mIdentifierProviderA; - private IdentifierProvider mIdentifierProviderB; + private IBandIdentifier mIdentifierProviderA; + private IBandIdentifier mIdentifierProviderB; public SecondaryControlChannelBroadcast( LDU1Message message ) { @@ -111,7 +111,7 @@ public class SecondaryControlChannelBroadcast extends LDU1Message } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getIdentifierA() ) { diff --git a/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java b/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java index 2f0caab2..60433ff1 100644 --- a/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java +++ b/src/decode/p25/message/ldu/lc/SecondaryControlChannelBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.ldu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.ldu.LDU1Message; import decode.p25.message.tsbk.osp.control.SystemService; @@ -26,8 +26,8 @@ public class SecondaryControlChannelBroadcastExplicit public static final int[] SYSTEM_SERVICE_CLASS = { 732,733,734,735,740,741, 742,743 }; - private IdentifierProvider mTransmitIdentifierProvider; - private IdentifierProvider mReceiveIdentifierProvider; + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; public SecondaryControlChannelBroadcastExplicit( LDU1Message message ) { @@ -104,7 +104,7 @@ public class SecondaryControlChannelBroadcastExplicit } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/pdu/PDUMessage.java b/src/decode/p25/message/pdu/PDUMessage.java index 15290b7a..18b17e8c 100644 --- a/src/decode/p25/message/pdu/PDUMessage.java +++ b/src/decode/p25/message/pdu/PDUMessage.java @@ -3,6 +3,7 @@ package decode.p25.message.pdu; import alias.AliasList; import bits.BinaryMessage; import decode.p25.message.P25Message; +import decode.p25.message.tsbk.vendor.VendorOpcode; import decode.p25.reference.DataUnitID; import decode.p25.reference.Opcode; import decode.p25.reference.PDUFormat; @@ -151,6 +152,16 @@ public class PDUMessage extends P25Message return Opcode.UNKNOWN; } + public VendorOpcode getVendorOpcode() + { + if( getFormat() == PDUFormat.ALTERNATE_MULTI_BLOCK_TRUNKING_CONTROL ) + { + return VendorOpcode.fromValue( mMessage.getInt( OPCODE ) ); + } + + return VendorOpcode.UNKNOWN; + } + public int getDataHeaderOffset() { return mMessage.getInt( DATA_HEADER_OFFSET ); diff --git a/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java b/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java index 6195f62f..e5c0c03c 100644 --- a/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java +++ b/src/decode/p25/message/pdu/UnitToUnitChannelGrantExtended.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; import decode.p25.reference.Opcode; @@ -39,8 +39,8 @@ public abstract class UnitToUnitChannelGrantExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public UnitToUnitChannelGrantExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -175,7 +175,7 @@ public abstract class UnitToUnitChannelGrantExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java index b12f9375..a685a213 100644 --- a/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java +++ b/src/decode/p25/message/pdu/osp/control/AdjacentStatusBroadcastExtended.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.message.tsbk.osp.control.SystemService; @@ -31,8 +31,8 @@ public class AdjacentStatusBroadcastExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierProvider; - private IdentifierProvider mReceiveIdentifierProvider; + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; public AdjacentStatusBroadcastExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -136,7 +136,7 @@ public class AdjacentStatusBroadcastExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java index f2e06dd6..730666de 100644 --- a/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java +++ b/src/decode/p25/message/pdu/osp/control/NetworkStatusBroadcastExtended.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.message.tsbk.osp.control.SystemService; @@ -31,8 +31,8 @@ public class NetworkStatusBroadcastExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public NetworkStatusBroadcastExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -135,7 +135,7 @@ public class NetworkStatusBroadcastExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java b/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java index d72cebde..00206dd1 100644 --- a/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java +++ b/src/decode/p25/message/pdu/osp/control/RFSSStatusBroadcastExtended.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.message.tsbk.osp.control.SystemService; @@ -31,8 +31,8 @@ public class RFSSStatusBroadcastExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public RFSSStatusBroadcastExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -139,7 +139,7 @@ public class RFSSStatusBroadcastExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java b/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java index 0335fba0..f8dd957a 100644 --- a/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java +++ b/src/decode/p25/message/pdu/osp/data/GroupDataChannelGrantExtended.java @@ -4,7 +4,7 @@ import java.util.Date; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.reference.DataUnitID; @@ -36,8 +36,8 @@ public class GroupDataChannelGrantExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public GroupDataChannelGrantExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -154,7 +154,7 @@ public class GroupDataChannelGrantExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java b/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java index ffa7dfbb..7ec29745 100644 --- a/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java +++ b/src/decode/p25/message/pdu/osp/voice/GroupVoiceChannelGrantExplicit.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu.osp.voice; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.reference.DataUnitID; @@ -34,8 +34,8 @@ public class GroupVoiceChannelGrantExplicit extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public GroupVoiceChannelGrantExplicit( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -152,7 +152,7 @@ public class GroupVoiceChannelGrantExplicit extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java index 9398c614..7bc32e65 100644 --- a/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java +++ b/src/decode/p25/message/pdu/osp/voice/TelephoneInterconnectChannelGrantExplicit.java @@ -4,7 +4,7 @@ import java.util.Date; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.reference.DataUnitID; @@ -36,8 +36,8 @@ public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public TelephoneInterconnectChannelGrantExplicit( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -159,7 +159,7 @@ public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java index 1900433f..4c3ac589 100644 --- a/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java +++ b/src/decode/p25/message/pdu/osp/voice/UnitToUnitVoiceChannelGrantUpdateExtended.java @@ -2,7 +2,7 @@ package decode.p25.message.pdu.osp.voice; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.pdu.PDUMessage; import decode.p25.reference.DataUnitID; @@ -40,8 +40,8 @@ public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage 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 IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public UnitToUnitVoiceChannelGrantUpdateExtended( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -182,7 +182,7 @@ public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/tdu/TDULinkControlMessage.java b/src/decode/p25/message/tdu/TDULinkControlMessage.java deleted file mode 100644 index 2c9f1468..00000000 --- a/src/decode/p25/message/tdu/TDULinkControlMessage.java +++ /dev/null @@ -1,265 +0,0 @@ -package decode.p25.message.tdu; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import alias.AliasList; -import bits.BinaryMessage; -import decode.p25.message.P25Message; -import decode.p25.reference.DataUnitID; -import decode.p25.reference.LinkControlOpcode; -import decode.p25.reference.Vendor; -import decode.p25.reference.VendorLinkControlOpcode; -import edac.CRC; -import edac.Galois24; -import edac.ReedSolomon_24_12_13; - -public class TDULinkControlMessage extends P25Message -{ - public final static Logger mLog = LoggerFactory.getLogger( TDULinkControlMessage.class ); - - public static final int[] LC_HEX_0 = { 64,65,66,67,68,69 }; - public static final int[] LC_HEX_1 = { 70,71,72,73,74,75 }; - public static final int[] LC_HEX_2 = { 88,89,90,91,92,93 }; - public static final int[] LC_HEX_3 = { 94,95,96,97,98,99 }; - public static final int[] LC_HEX_4 = { 112,113,114,115,116,117 }; - public static final int[] LC_HEX_5 = { 118,119,120,121,122,123 }; - public static final int[] LC_HEX_6 = { 136,137,138,139,140,141 }; - public static final int[] LC_HEX_7 = { 142,143,144,145,146,147 }; - public static final int[] LC_HEX_8 = { 160,161,162,163,164,165 }; - public static final int[] LC_HEX_9 = { 166,167,168,169,170,171 }; - public static final int[] LC_HEX_10 = { 184,185,186,187,188,189 }; - public static final int[] LC_HEX_11 = { 190,191,192,193,194,195 }; - public static final int[] RS_HEX_0 = { 208,209,210,211,212,213 }; - public static final int[] RS_HEX_1 = { 214,215,216,217,218,219 }; - public static final int[] RS_HEX_2 = { 232,233,234,235,236,237 }; - public static final int[] RS_HEX_3 = { 238,239,240,241,242,243 }; - public static final int[] RS_HEX_4 = { 256,257,258,259,260,261 }; - public static final int[] RS_HEX_5 = { 262,263,264,265,266,267 }; - public static final int[] RS_HEX_6 = { 280,281,282,283,284,285 }; - public static final int[] RS_HEX_7 = { 286,287,288,289,290,291 }; - public static final int[] RS_HEX_8 = { 304,305,306,307,308,309 }; - public static final int[] RS_HEX_9 = { 310,311,312,313,314,315 }; - public static final int[] RS_HEX_10 = { 328,329,330,331,332,333 }; - public static final int[] RS_HEX_11 = { 334,335,336,337,338,339 }; - - public static final int ENCRYPTION_FLAG = 64; - public static final int IMPLICIT_VENDOR_FLAG = 65; - public static final int[] OPCODE = { 66,67,68,69,70,71 }; - public static final int[] VENDOR = { 72,73,74,75,88,89,90,91 }; - - public static final ReedSolomon_24_12_13 mReedSolomonDecoder = - new ReedSolomon_24_12_13(); - - public TDULinkControlMessage( BinaryMessage message, DataUnitID duid, - AliasList aliasList ) - { - super( message, duid, aliasList ); - - /* NID CRC is checked in the message framer so a constructed message - * means it passed the CRC */ - mCRC = new CRC[ 3 ]; - mCRC[ 0 ] = CRC.PASSED; - - checkCRC(); - } - - /** - * Constructs a TDULinkControl message from an existing message and bypasses - * the CRC calculation. - */ - protected TDULinkControlMessage( TDULinkControlMessage message ) - { - super( message.getSourceMessage(), DataUnitID.TDULC, message.getAliasList() ); - - mCRC = message.getCRC(); - } - - public CRC[] getCRC() - { - return mCRC; - } - - @Override - public String getMessage() - { - StringBuilder sb = new StringBuilder(); - - sb.append( getMessageStub() ); - sb.append( " " ); - sb.append( mMessage.toString() ); - - return sb.toString(); - } - - public String getMessageStub() - { - StringBuilder sb = new StringBuilder(); - - sb.append( "NAC:" ); - sb.append( getNAC() ); - sb.append( " " ); - sb.append( getDUID().getLabel() ); - sb.append( " " ); - - if( isEncrypted() ) - { - sb.append( "ENCRYPTED" ); - } - else - { - if( isImplicitFormat() || getVendor() == Vendor.STANDARD ) - { - sb.append( getOpcode().getLabel() ); - } - else - { - sb.append( "VENDOR:" + getVendor().getLabel() + " " ); - sb.append( getVendorOpcode().getLabel() ); - } - } - - return sb.toString(); - } - - public boolean isEncrypted() - { - return mMessage.get( ENCRYPTION_FLAG ); - } - - public boolean isImplicitFormat() - { - return mMessage.get( IMPLICIT_VENDOR_FLAG ); - } - - public LinkControlOpcode getOpcode() - { - return LinkControlOpcode.fromValue( mMessage.getInt( OPCODE ) ); - } - - public VendorLinkControlOpcode getVendorOpcode() - { - return VendorLinkControlOpcode.fromValue( mMessage.getInt( OPCODE ) ); - } - - public Vendor getVendor() - { - if( isImplicitFormat() ) - { - return Vendor.STANDARD; - } - - return Vendor.fromValue( mMessage.getInt( VENDOR ) ); - } - - - /** - * Checks and repairs the 12 x 24-bit golay(24,12,8) codewords and then - * checks and repairs the 24 x 6-bit link control and reed-solomon - * RS(24,12,13) parity codewords - */ - private void checkCRC() - { - /* Check the Golay codewords */ - int x = 64; - - mCRC[ 1 ] = CRC.PASSED; - - while( x < mMessage.size() ) - { - mMessage = Galois24.checkAndCorrect( mMessage, x ); - - if( !( mMessage.getCRC() == CRC.PASSED ) ) - { - mCRC[ 1 ] = CRC.FAILED_CRC; - } - - x += 24; - } - - /* Check the Reed-Solomon parity bits. The RS decoder expects the link - * control data and reed solomon parity hex codewords in reverse order. - * The RS(24,12,13) code used by P25 removes the left-hand 47 data hex - * words, so we replace them with zeros. */ - int[] input = new int [63]; - int[] output = new int [63]; - - input[ 0 ] = mMessage.getInt( RS_HEX_11 ); - input[ 1 ] = mMessage.getInt( RS_HEX_10 ); - input[ 2 ] = mMessage.getInt( RS_HEX_9 ); - input[ 3 ] = mMessage.getInt( RS_HEX_8 ); - input[ 4 ] = mMessage.getInt( RS_HEX_7 ); - input[ 5 ] = mMessage.getInt( RS_HEX_6 ); - input[ 6 ] = mMessage.getInt( RS_HEX_5 ); - input[ 7 ] = mMessage.getInt( RS_HEX_4 ); - input[ 8 ] = mMessage.getInt( RS_HEX_3 ); - input[ 9 ] = mMessage.getInt( RS_HEX_2 ); - input[ 10 ] = mMessage.getInt( RS_HEX_1 ); - input[ 11 ] = mMessage.getInt( RS_HEX_0 ); - input[ 12 ] = mMessage.getInt( LC_HEX_11 ); - input[ 13 ] = mMessage.getInt( LC_HEX_10 ); - input[ 14 ] = mMessage.getInt( LC_HEX_9 ); - input[ 15 ] = mMessage.getInt( LC_HEX_8 ); - input[ 16 ] = mMessage.getInt( LC_HEX_7 ); - input[ 17 ] = mMessage.getInt( LC_HEX_6 ); - input[ 18 ] = mMessage.getInt( LC_HEX_5 ); - input[ 19 ] = mMessage.getInt( LC_HEX_4 ); - input[ 20 ] = mMessage.getInt( LC_HEX_3 ); - input[ 21 ] = mMessage.getInt( LC_HEX_2 ); - input[ 22 ] = mMessage.getInt( LC_HEX_1 ); - input[ 23 ] = mMessage.getInt( LC_HEX_0 ); - /* indexes 24 - 62 are defaulted to zero */ - - boolean irrecoverableErrors = mReedSolomonDecoder.decode( input, output ); - - if( irrecoverableErrors ) - { - mCRC[ 2 ] = CRC.FAILED_CRC; - } - else - { - mCRC[ 2 ] = CRC.PASSED; - - /* Only fix the link control data hex codewords */ - repairHexCodeword( input, output, 12, LC_HEX_11 ); - repairHexCodeword( input, output, 13, LC_HEX_10 ); - repairHexCodeword( input, output, 14, LC_HEX_9 ); - repairHexCodeword( input, output, 15, LC_HEX_8 ); - repairHexCodeword( input, output, 16, LC_HEX_7 ); - repairHexCodeword( input, output, 17, LC_HEX_6 ); - repairHexCodeword( input, output, 18, LC_HEX_5 ); - repairHexCodeword( input, output, 19, LC_HEX_4 ); - repairHexCodeword( input, output, 20, LC_HEX_3 ); - repairHexCodeword( input, output, 21, LC_HEX_2 ); - repairHexCodeword( input, output, 22, LC_HEX_1 ); - repairHexCodeword( input, output, 23, LC_HEX_0 ); - - /* If the golay check failed, mark it as corrected too */ - if( mCRC[ 1 ] == CRC.FAILED_CRC ) - { - mCRC[ 1 ] = CRC.CORRECTED; - } - } - } - - private void repairHexCodeword( int[] input, int[] output, int index, int[] indexSet ) - { - if( input[ index ] != output[ index ] ) - { - mMessage.load( indexSet[ 0 ], 6, output[ index ] ); - mCRC[ 2 ] = CRC.CORRECTED; - } - } - - /** - * Indicates if the message passed the golay and reed-solomon parity checks - * or was corrected. - */ - public boolean isValid() - { - // mCRC[ 0 ] - always passes (otherwise message wouldn't be constructed ) - // mCRC[ 1 ] - golay - always passes or corrected if mCRC[2] is valid - - return mCRC[ 2 ] == CRC.PASSED || mCRC[ 2 ] == CRC.CORRECTED; - } -} diff --git a/src/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java b/src/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java index 8d9eaf04..ae47e968 100644 --- a/src/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java +++ b/src/decode/p25/message/tdu/lc/AdjacentSiteStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.osp.control.SystemService; import decode.p25.reference.LinkControlOpcode; @@ -26,7 +26,7 @@ public class AdjacentSiteStatusBroadcast extends TDULinkControlMessage public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, 194,195 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public AdjacentSiteStatusBroadcast( TDULinkControlMessage source ) { @@ -100,7 +100,7 @@ public class AdjacentSiteStatusBroadcast extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tdu/lc/CallTermination.java b/src/decode/p25/message/tdu/lc/CallTermination.java index f1218c95..81e5d699 100644 --- a/src/decode/p25/message/tdu/lc/CallTermination.java +++ b/src/decode/p25/message/tdu/lc/CallTermination.java @@ -30,7 +30,7 @@ public class CallTermination extends TDULinkControlMessage sb.append( getMessageStub() ); - sb.append( " FROM:" + getSourceAddress() ); + sb.append( " BY:" + getSourceAddress() ); return sb.toString(); } diff --git a/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java b/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java index a17627a7..db607906 100644 --- a/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java +++ b/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdate.java @@ -3,11 +3,11 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.reference.LinkControlOpcode; public class ChannelIdentifierUpdate extends TDULinkControlMessage - implements IdentifierProvider + implements IBandIdentifier { private final static Logger mLog = LoggerFactory.getLogger( ChannelIdentifierUpdate.class ); diff --git a/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java b/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java index 4d001db3..3aa1a959 100644 --- a/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java +++ b/src/decode/p25/message/tdu/lc/ChannelIdentifierUpdateExplicit.java @@ -3,11 +3,11 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.reference.LinkControlOpcode; public class ChannelIdentifierUpdateExplicit extends TDULinkControlMessage - implements IdentifierProvider + implements IBandIdentifier { private final static Logger mLog = LoggerFactory.getLogger( ChannelIdentifierUpdateExplicit.class ); diff --git a/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java b/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java index 57d1b55f..579d0db5 100644 --- a/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java +++ b/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdate.java @@ -1,9 +1,12 @@ package decode.p25.message.tdu.lc; +import java.util.Set; +import java.util.TreeSet; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.LinkControlOpcode; @@ -23,8 +26,8 @@ public class GroupVoiceChannelUpdate extends TDULinkControlMessage public static final int[] GROUP_ADDRESS_B = { 168,169,170,171,184,185,186, 187,188,189,190,191,192,193,194,195 }; - private IdentifierProvider mIdentifierUpdateA; - private IdentifierProvider mIdentifierUpdateB; + private IBandIdentifier mIdentifierUpdateA; + private IBandIdentifier mIdentifierUpdateB; public GroupVoiceChannelUpdate( TDULinkControlMessage source ) { @@ -103,8 +106,23 @@ public class GroupVoiceChannelUpdate extends TDULinkControlMessage return mMessage.getHex( GROUP_ADDRESS_B, 4 ); } + /** + * Returns a sorted list of addresses contained in the A and B fields + * @return + */ + public Set getAddresses() + { + Set addresses = new TreeSet(); + + addresses.add( getGroupAddressA() ); + addresses.add( getGroupAddressB() ); + + return addresses; + } + + @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getChannelIdentifierA() ) { diff --git a/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java b/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java index ba857730..a934e37f 100644 --- a/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java +++ b/src/decode/p25/message/tdu/lc/GroupVoiceChannelUpdateExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.P25Message.DuplexMode; import decode.p25.message.P25Message.SessionMode; @@ -28,8 +28,8 @@ public class GroupVoiceChannelUpdateExplicit extends TDULinkControlMessage public static final int[] RECEIVE_CHANNEL = { 184,185,186,187,188,189,190, 191,192,193,194,195,196,197,198,199 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public GroupVoiceChannelUpdateExplicit( TDULinkControlMessage source ) { @@ -119,7 +119,7 @@ public class GroupVoiceChannelUpdateExplicit extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java b/src/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java index 317c7d12..a240a49b 100644 --- a/src/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java +++ b/src/decode/p25/message/tdu/lc/NetworkStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.LinkControlOpcode; import decode.p25.reference.Service; @@ -13,9 +13,10 @@ public class NetworkStatusBroadcast extends TDULinkControlMessage { private final static Logger mLog = LoggerFactory.getLogger( NetworkStatusBroadcast.class ); - public static final int[] NETWORK_ID = { 72,73,74,75,88,89,90,91,92,93,94, - 95,96,97,98,99,112,113,114,115,116,117,118,119,120,121,122,123 }; - public static final int[] SYSTEM_ID = { 136,137,138,139,140,141,142,143,144, + + public static final int[] WACN = { 72,73,74,75,88,89,90,91,92,93,94,95,96, + 97,98,99,112,113,114,115,116,117,118,119,120,121,122,123 }; + public static final int[] SYSTEM = { 136,137,138,139,140,141,142,143,144, 145,146,147 }; public static final int[] IDENTIFIER = { 160,161,162,163 }; public static final int[] CHANNEL = { 164,165,166,167,168,169,170,171,184, @@ -23,7 +24,7 @@ public class NetworkStatusBroadcast extends TDULinkControlMessage public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, 194,195 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public NetworkStatusBroadcast( TDULinkControlMessage source ) { @@ -43,22 +44,22 @@ public class NetworkStatusBroadcast extends TDULinkControlMessage sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); + sb.append( " NETWORK:" + getWACN() ); + sb.append( " SYS:" + getSystem() ); sb.append( " CHAN:" + getChannel() ); sb.append( " " + Service.getServices( getSystemServiceClass() ).toString() ); return sb.toString(); } - public String getNetworkID() + public String getWACN() { - return mMessage.getHex( NETWORK_ID, 5 ); + return mMessage.getHex( WACN, 5 ); } - public String getSystemID() + public String getSystem() { - return mMessage.getHex( SYSTEM_ID, 3 ); + return mMessage.getHex( SYSTEM, 3 ); } public int getIdentifier() @@ -82,7 +83,7 @@ public class NetworkStatusBroadcast extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java b/src/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java index 17d466d1..db36edc5 100644 --- a/src/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java +++ b/src/decode/p25/message/tdu/lc/NetworkStatusBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.LinkControlOpcode; import decode.p25.reference.Service; @@ -13,9 +13,10 @@ public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage { private final static Logger mLog = LoggerFactory.getLogger( NetworkStatusBroadcastExplicit.class ); - public static final int[] NETWORK_ID = { 72,73,74,75,88,89,90,91,92,93,94, - 95,96,97,98,99,112,113,114,115 }; - public static final int[] SYSTEM_ID = { 116,117,118,119,120,121,122,123,136, + + public static final int[] WACN = { 72,73,74,75,88,89,90,91,92,93,94,95,96, + 97,98,99,112,113,114,115 }; + public static final int[] SYSTEM = { 116,117,118,119,120,121,122,123,136, 137,138,139 }; public static final int[] TRANSMIT_IDENTIFIER = { 140,141,142,143 }; public static final int[] TRANSMIT_CHANNEL = { 144,145,146,147,160,161,162, @@ -24,8 +25,8 @@ public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage public static final int[] RECEIVE_CHANNEL = { 184,185,186,187,188,189,190, 191,192,193,194,195 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public NetworkStatusBroadcastExplicit( TDULinkControlMessage source ) { @@ -45,22 +46,22 @@ public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); + sb.append( " NETWORK:" + getWACN() ); + sb.append( " SYS:" + getSystem() ); sb.append( " TRANSMIT:" + getTransmitChannel() ); sb.append( " RECEIVE:" + getReceiveChannel() ); return sb.toString(); } - public String getNetworkID() + public String getWACN() { - return mMessage.getHex( NETWORK_ID, 5 ); + return mMessage.getHex( WACN, 5 ); } - public String getSystemID() + public String getSystem() { - return mMessage.getHex( SYSTEM_ID, 3 ); + return mMessage.getHex( SYSTEM, 3 ); } public int getTransmitIdentifier() @@ -94,7 +95,7 @@ public class NetworkStatusBroadcastExplicit extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java b/src/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java index 3364a62b..d67fbb7b 100644 --- a/src/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java +++ b/src/decode/p25/message/tdu/lc/RFSSStatusBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.osp.control.SystemService; import decode.p25.reference.LinkControlOpcode; @@ -28,7 +28,7 @@ public class RFSSStatusBroadcast extends TDULinkControlMessage public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, 194,195 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public RFSSStatusBroadcast( TDULinkControlMessage source ) { @@ -104,7 +104,7 @@ public class RFSSStatusBroadcast extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java b/src/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java index c4cfe45d..acfca7cf 100644 --- a/src/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java +++ b/src/decode/p25/message/tdu/lc/RFSSStatusBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.osp.control.SystemService; import decode.p25.reference.LinkControlOpcode; @@ -28,8 +28,8 @@ public class RFSSStatusBroadcastExplicit extends TDULinkControlMessage public static final int[] SYSTEM_SERVICE_CLASS = { 188,189,190,191,192,193, 194,195 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public RFSSStatusBroadcastExplicit( TDULinkControlMessage source ) { @@ -115,7 +115,7 @@ public class RFSSStatusBroadcastExplicit extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java b/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java index 3170a3c0..d454c2e3 100644 --- a/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java +++ b/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcast.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.osp.control.SystemService; import decode.p25.reference.LinkControlOpcode; @@ -29,8 +29,8 @@ public class SecondaryControlChannelBroadcast extends TDULinkControlMessage public static final int[] SYSTEM_SERVICE_CLASS_B = { 188,189,190,191,192, 193,194,195 }; - private IdentifierProvider mIdentifierProviderA; - private IdentifierProvider mIdentifierProviderB; + private IBandIdentifier mIdentifierProviderA; + private IBandIdentifier mIdentifierProviderB; public SecondaryControlChannelBroadcast( TDULinkControlMessage source ) { @@ -114,7 +114,7 @@ public class SecondaryControlChannelBroadcast extends TDULinkControlMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getIdentifierA() ) { diff --git a/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java b/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java index efa6657b..6607c7e2 100644 --- a/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java +++ b/src/decode/p25/message/tdu/lc/SecondaryControlChannelBroadcastExplicit.java @@ -3,7 +3,7 @@ package decode.p25.message.tdu.lc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.osp.control.SystemService; import decode.p25.reference.LinkControlOpcode; @@ -25,8 +25,8 @@ public class SecondaryControlChannelBroadcastExplicit public static final int[] SYSTEM_SERVICE_CLASS = { 168,169,170,171,184, 185,186,187 }; - private IdentifierProvider mTransmitIdentifierProvider; - private IdentifierProvider mReceiveIdentifierProvider; + private IBandIdentifier mTransmitIdentifierProvider; + private IBandIdentifier mReceiveIdentifierProvider; public SecondaryControlChannelBroadcastExplicit( TDULinkControlMessage source ) { @@ -103,7 +103,7 @@ public class SecondaryControlChannelBroadcastExplicit } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitIdentifier() ) { diff --git a/src/decode/p25/message/tdu/lc/TDULCMessageFactory.java b/src/decode/p25/message/tdu/lc/TDULCMessageFactory.java index 3ee2d77a..230348c2 100644 --- a/src/decode/p25/message/tdu/lc/TDULCMessageFactory.java +++ b/src/decode/p25/message/tdu/lc/TDULCMessageFactory.java @@ -85,6 +85,7 @@ public class TDULCMessageFactory { switch( message.getVendor() ) { + case MOTOROLA: default: break; } diff --git a/src/decode/p25/message/tdu/lc/TDULinkControlMessage.java b/src/decode/p25/message/tdu/lc/TDULinkControlMessage.java index 6efebdaf..a77d109e 100644 --- a/src/decode/p25/message/tdu/lc/TDULinkControlMessage.java +++ b/src/decode/p25/message/tdu/lc/TDULinkControlMessage.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import alias.AliasList; import bits.BinaryMessage; import decode.p25.message.P25Message; +import decode.p25.message.tsbk.motorola.MotorolaOpcode; import decode.p25.reference.DataUnitID; import decode.p25.reference.LinkControlOpcode; import decode.p25.reference.Vendor; @@ -131,16 +132,31 @@ public class TDULinkControlMessage extends P25Message { return mMessage.get( IMPLICIT_VENDOR_FLAG ); } - + + /** + * Standard opcodes when the Vendor is STANDARD + */ public LinkControlOpcode getOpcode() { return LinkControlOpcode.fromValue( mMessage.getInt( OPCODE ) ); } + /** + * Returns a generic vendor-neutral opcode. Use this when there is a non + * standard vendor code. + */ public VendorLinkControlOpcode getVendorOpcode() { return VendorLinkControlOpcode.fromValue( mMessage.getInt( OPCODE ) ); } + + /** + * If the vendor is motorola, returns the Motorola OPCODE for this message + */ + public MotorolaOpcode getMotorolaOpcode() + { + return MotorolaOpcode.fromValue( mMessage.getInt( OPCODE ) ); + } public Vendor getVendor() { diff --git a/src/decode/p25/message/tsbk/ChannelGrant.java b/src/decode/p25/message/tsbk/ChannelGrant.java index 0b7d3a59..f419a4cd 100644 --- a/src/decode/p25/message/tsbk/ChannelGrant.java +++ b/src/decode/p25/message/tsbk/ChannelGrant.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -14,7 +14,7 @@ public abstract class ChannelGrant extends ServiceMessage public static final int[] CHANNEL_NUMBER = { 92,93,94,95,96,97,98,99,100, 101,102,103 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public ChannelGrant( BinaryMessage message, DataUnitID duid, @@ -47,7 +47,7 @@ public abstract class ChannelGrant extends ServiceMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java b/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java index c35f196e..7bf8d4a7 100644 --- a/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java +++ b/src/decode/p25/message/tsbk/GroupChannelGrantExplicit.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.reference.DataUnitID; public abstract class GroupChannelGrantExplicit extends ChannelGrant @@ -16,8 +16,8 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant public static final int[] GROUP_ADDRESS = { 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143 }; - private IdentifierProvider mTransmitIdentifierUpdate; - private IdentifierProvider mReceiveIdentifierUpdate; + private IBandIdentifier mTransmitIdentifierUpdate; + private IBandIdentifier mReceiveIdentifierUpdate; public GroupChannelGrantExplicit( BinaryMessage message, DataUnitID duid, @@ -85,7 +85,7 @@ public abstract class GroupChannelGrantExplicit extends ChannelGrant } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java b/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java index 553db4e1..41262669 100644 --- a/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java +++ b/src/decode/p25/message/tsbk/GroupMultiChannelGrant.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -21,8 +21,8 @@ public abstract class GroupMultiChannelGrant extends ChannelGrant public static final int[] GROUP_ADDRESS_2 = { 128,129,130,131,132,133,134, 135,136,137,138,139,140,141,142,143 }; - private IdentifierProvider mIdentifierUpdate1; - private IdentifierProvider mIdentifierUpdate2; + private IBandIdentifier mIdentifierUpdate1; + private IBandIdentifier mIdentifierUpdate2; public GroupMultiChannelGrant( BinaryMessage message, DataUnitID duid, @@ -114,7 +114,7 @@ public abstract class GroupMultiChannelGrant extends ChannelGrant } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getChannelIdentifier1() ) { diff --git a/src/decode/p25/message/tsbk/motorola/ChannelCWIDUpdate.java b/src/decode/p25/message/tsbk/motorola/ChannelCWIDUpdate.java index fc11f203..3720f52f 100644 --- a/src/decode/p25/message/tsbk/motorola/ChannelCWIDUpdate.java +++ b/src/decode/p25/message/tsbk/motorola/ChannelCWIDUpdate.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.motorola; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -22,7 +22,7 @@ public class ChannelCWIDUpdate extends MotorolaTSBKMessage public static final int[] CHANNEL = { 132,133,134,135,136,137,138,139,140, 141,142,143 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public ChannelCWIDUpdate( BinaryMessage message, DataUnitID duid, @@ -104,7 +104,7 @@ public class ChannelCWIDUpdate extends MotorolaTSBKMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tsbk/motorola/PatchGroup.java b/src/decode/p25/message/tsbk/motorola/PatchGroup.java index 0665b138..594635f8 100644 --- a/src/decode/p25/message/tsbk/motorola/PatchGroup.java +++ b/src/decode/p25/message/tsbk/motorola/PatchGroup.java @@ -59,6 +59,4 @@ public abstract class PatchGroup extends MotorolaTSBKMessage { return mMessage.getHex( GROUP_ADDRESS_3, 4 ); } - - } diff --git a/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java b/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java index 75bb11f1..4993cb8d 100644 --- a/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java +++ b/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrant.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.motorola; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -24,7 +24,7 @@ public class PatchGroupVoiceChannelGrant extends MotorolaTSBKMessage 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 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public PatchGroupVoiceChannelGrant( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -122,7 +122,7 @@ public class PatchGroupVoiceChannelGrant extends MotorolaTSBKMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { mIdentifierUpdate = message; } diff --git a/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java b/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java index 51eb2712..612fa27e 100644 --- a/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java +++ b/src/decode/p25/message/tsbk/motorola/PatchGroupVoiceChannelGrantUpdate.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.motorola; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -20,8 +20,8 @@ public class PatchGroupVoiceChannelGrantUpdate extends MotorolaTSBKMessage public static final int[] PATCH_GROUP_ADDRESS_2 = { 128,129,130,131,132,133, 134,135,136,137,138,139,140,141,142,143 }; - private IdentifierProvider mIdentifierUpdate1; - private IdentifierProvider mIdentifierUpdate2; + private IBandIdentifier mIdentifierUpdate1; + private IBandIdentifier mIdentifierUpdate2; public PatchGroupVoiceChannelGrantUpdate( BinaryMessage message, DataUnitID duid, AliasList aliasList ) @@ -100,7 +100,7 @@ public class PatchGroupVoiceChannelGrantUpdate extends MotorolaTSBKMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getChannelIdentifier1() ) { diff --git a/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java index 9924d9c3..b51d91da 100644 --- a/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/AdjacentStatusBroadcast.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.reference.DataUnitID; @@ -26,7 +26,7 @@ public class AdjacentStatusBroadcast extends TSBKMessage implements IdentifierRe public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, 142,143 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public AdjacentStatusBroadcast( BinaryMessage message, DataUnitID duid, @@ -163,7 +163,7 @@ public class AdjacentStatusBroadcast extends TSBKMessage implements IdentifierRe } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { /* we're only expecting 1 identifier, so use whatever is received */ mIdentifierUpdate = message; diff --git a/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java b/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java index b9e2ba66..6df9feb9 100644 --- a/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java +++ b/src/decode/p25/message/tsbk/osp/control/IdentifierUpdate.java @@ -2,12 +2,12 @@ package decode.p25.message.tsbk.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.reference.DataUnitID; public abstract class IdentifierUpdate extends TSBKMessage - implements IdentifierProvider + implements IBandIdentifier { public static final int[] IDENTIFIER = { 80,81,82,83 }; diff --git a/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java index 0fdb25ec..fcce3e48 100644 --- a/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/NetworkStatusBroadcast.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.reference.DataUnitID; @@ -23,7 +23,7 @@ public class NetworkStatusBroadcast extends TSBKMessage implements IdentifierRec public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, 142,143 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public NetworkStatusBroadcast( BinaryMessage message, DataUnitID duid, @@ -109,7 +109,7 @@ public class NetworkStatusBroadcast extends TSBKMessage implements IdentifierRec } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { /* we're only expecting 1 identifier, so use whatever is received */ mIdentifierUpdate = message; diff --git a/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java b/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java index 5b5b6742..1939bb93 100644 --- a/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/RFSSStatusBroadcast.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.osp.control; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.reference.DataUnitID; @@ -23,7 +23,7 @@ public class RFSSStatusBroadcast extends TSBKMessage implements IdentifierReceiv public static final int[] SYSTEM_SERVICE_CLASS = { 136,137,138,139,140,141, 142,143 }; - private IdentifierProvider mIdentifierUpdate; + private IBandIdentifier mIdentifierUpdate; public RFSSStatusBroadcast( BinaryMessage message, DataUnitID duid, @@ -119,7 +119,7 @@ public class RFSSStatusBroadcast extends TSBKMessage implements IdentifierReceiv } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { /* we're only expecting 1 identifier, so use whatever is received */ mIdentifierUpdate = message; diff --git a/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java b/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java index 3fb885d7..ac4cb6b6 100644 --- a/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java +++ b/src/decode/p25/message/tsbk/osp/control/SecondaryControlChannelBroadcast.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.reference.DataUnitID; @@ -30,8 +30,8 @@ public class SecondaryControlChannelBroadcast extends TSBKMessage public static final int[] SYSTEM_SERVICE_CLASS_2 = { 136,137,138,139,140, 141,142,143 }; - private IdentifierProvider mIdentifierUpdate1; - private IdentifierProvider mIdentifierUpdate2; + private IBandIdentifier mIdentifierUpdate1; + private IBandIdentifier mIdentifierUpdate2; public SecondaryControlChannelBroadcast( BinaryMessage message, DataUnitID duid, @@ -145,7 +145,7 @@ public class SecondaryControlChannelBroadcast extends TSBKMessage } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getIdentifier1() ) { diff --git a/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java b/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java index 90dc4636..31a99e01 100644 --- a/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java +++ b/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelAnnouncementExplicit.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.osp.data; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -22,8 +22,8 @@ public class SNDCPDataChannelAnnouncementExplicit extends SNDCPData public static final int[] DATA_ACCESS_CONTROL = { 128,129,130,131,132,133, 134,135,136,137,138,139,140,141,142,143 }; - private IdentifierProvider mIdentifierUpdateTransmit; - private IdentifierProvider mIdentifierUpdateReceive; + private IBandIdentifier mIdentifierUpdateTransmit; + private IBandIdentifier mIdentifierUpdateReceive; public SNDCPDataChannelAnnouncementExplicit( BinaryMessage message, DataUnitID duid, @@ -118,7 +118,7 @@ public class SNDCPDataChannelAnnouncementExplicit extends SNDCPData } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java b/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java index e85ebe13..06c451c0 100644 --- a/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java +++ b/src/decode/p25/message/tsbk/osp/data/SNDCPDataChannelGrant.java @@ -2,7 +2,7 @@ package decode.p25.message.tsbk.osp.data; import alias.AliasList; import bits.BinaryMessage; -import decode.p25.message.IdentifierProvider; +import decode.p25.message.IBandIdentifier; import decode.p25.message.IdentifierReceiver; import decode.p25.reference.DataUnitID; @@ -18,8 +18,8 @@ public class SNDCPDataChannelGrant extends SNDCPData implements IdentifierReceiv 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 }; - private IdentifierProvider mIdentifierUpdateTransmit; - private IdentifierProvider mIdentifierUpdateReceive; + private IBandIdentifier mIdentifierUpdateTransmit; + private IBandIdentifier mIdentifierUpdateReceive; public SNDCPDataChannelGrant( BinaryMessage message, DataUnitID duid, @@ -91,7 +91,7 @@ public class SNDCPDataChannelGrant extends SNDCPData implements IdentifierReceiv } @Override - public void setIdentifierMessage( int identifier, IdentifierProvider message ) + public void setIdentifierMessage( int identifier, IBandIdentifier message ) { if( identifier == getTransmitChannelIdentifier() ) { diff --git a/src/decode/p25/reference/VendorLinkControlOpcode.java b/src/decode/p25/reference/VendorLinkControlOpcode.java index 886a49cf..e32d2c06 100644 --- a/src/decode/p25/reference/VendorLinkControlOpcode.java +++ b/src/decode/p25/reference/VendorLinkControlOpcode.java @@ -2,71 +2,71 @@ package decode.p25.reference; public enum VendorLinkControlOpcode { - RESERVED_00( "RESERVED_00 ", "Reserved", 0 ), - RESERVED_01( "RESERVED_01 ", "Reserved", 1 ), - RESERVED_02( "RESERVED_02 ", "Reserved", 2 ), - RESERVED_03( "RESERVED_03 ", "Reserved", 3 ), - RESERVED_04( "RESERVED_04 ", "Reserved", 4 ), - RESERVED_05( "RESERVED_05 ", "Reserved", 5 ), - RESERVED_06( "RESERVED_06 ", "Reserved", 6 ), - RESERVED_07( "RESERVED_07 ", "Reserved", 7 ), - RESERVED_08( "RESERVED_0B ", "Reserved", 8 ), - RESERVED_09( "RESERVED_0B ", "Reserved", 9 ), - RESERVED_0A( "RESERVED_0B ", "Reserved", 10 ), - RESERVED_0B( "RESERVED_0B ", "Reserved", 11 ), - RESERVED_0C( "RESERVED_0C ", "Reserved", 12 ), - RESERVED_0D( "RESERVED_0D ", "Reserved", 13 ), - RESERVED_0E( "RESERVED_0E ", "Reserved", 14 ), - RESERVED_0F( "RESERVED_0F ", "Reserved", 15 ), - RESERVED_10( "RESERVED_10 ", "Reserved", 16 ), - RESERVED_11( "RESERVED_11 ", "Reserved", 17 ), - RESERVED_12( "RESERVED_12 ", "Reserved", 18 ), - RESERVED_13( "RESERVED_13 ", "Reserved", 19 ), - RESERVED_14( "RESERVED_14 ", "Reserved", 20 ), - RESERVED_15( "RESERVED_15 ", "Reserved", 21 ), - RESERVED_16( "RESERVED_16 ", "Reserved", 22 ), - RESERVED_17( "RESERVED_17 ", "Reserved", 23 ), - RESERVED_18( "RESERVED_18 ", "Reserved", 24 ), - RESERVED_19( "RESERVED_19 ", "Reserved", 25 ), - RESERVED_1A( "RESERVED_1A ", "Reserved", 26 ), - RESERVED_1B( "RESERVED_1B ", "Reserved", 27 ), - RESERVED_1C( "RESERVED_1C ", "Reserved", 28 ), - RESERVED_1D( "RESERVED_1D ", "Reserved", 29 ), - RESERVED_1E( "RESERVED_1E ", "Reserved", 30 ), - RESERVED_1F( "RESERVED_1F ", "Reserved", 31 ), - RESERVED_20( "RESERVED_20 ", "Reserved", 32 ), - RESERVED_21( "RESERVED_21 ", "Reserved", 33 ), - RESERVED_22( "RESERVED_22 ", "Reserved", 34 ), - RESERVED_23( "RESERVED_23 ", "Reserved", 35 ), - RESERVED_24( "RESERVED_24 ", "Reserved", 36 ), - RESERVED_25( "RESERVED_25 ", "Reserved", 37 ), - RESERVED_26( "RESERVED_26 ", "Reserved", 38 ), - RESERVED_27( "RESERVED_27 ", "Reserved", 39 ), - RESERVED_28( "RESERVED_28 ", "Reserved", 40 ), - RESERVED_29( "RESERVED_29 ", "Reserved", 41 ), - RESERVED_2A( "RESERVED_2A ", "Reserved", 42 ), - RESERVED_2B( "RESERVED_2B ", "Reserved", 43 ), - RESERVED_2C( "RESERVED_2C ", "Reserved", 44 ), - RESERVED_2D( "RESERVED_2D ", "Reserved", 45 ), - RESERVED_2E( "RESERVED_2E ", "Reserved", 46 ), - RESERVED_2F( "RESERVED_2F ", "Reserved", 47 ), - RESERVED_30( "RESERVED_30 ", "Reserved", 48 ), - RESERVED_31( "RESERVED_31 ", "Reserved", 49 ), - RESERVED_32( "RESERVED_32 ", "Reserved", 50 ), - RESERVED_33( "RESERVED_33 ", "Reserved", 51 ), - RESERVED_34( "RESERVED_34 ", "Reserved", 52 ), - RESERVED_35( "RESERVED_35 ", "Reserved", 53 ), - RESERVED_36( "RESERVED_36 ", "Reserved", 54 ), - RESERVED_37( "RESERVED_37 ", "Reserved", 55 ), - RESERVED_38( "RESERVED_38 ", "Reserved", 56 ), - RESERVED_39( "RESERVED_39 ", "Reserved", 57 ), - RESERVED_3A( "RESERVED_3A ", "Reserved", 58 ), - RESERVED_3B( "RESERVED_3B ", "Reserved", 59 ), - RESERVED_3C( "RESERVED_3C ", "Reserved", 60 ), - RESERVED_3D( "RESERVED_3D ", "Reserved", 61 ), - RESERVED_3E( "RESERVED_3E ", "Reserved", 62 ), - RESERVED_3F( "RESERVED_3F ", "Reserved", 63 ), - UNKNOWN( "UNKNOWN ", "Unknown", -1 ); + RESERVED_00( "OPCODE_00", "RESERVED", 0 ), + RESERVED_01( "OPCODE_01", "RESERVED", 1 ), + RESERVED_02( "OPCODE_02", "RESERVED", 2 ), + RESERVED_03( "OPCODE_03", "RESERVED", 3 ), + RESERVED_04( "OPCODE_04", "RESERVED", 4 ), + RESERVED_05( "OPCODE_05", "RESERVED", 5 ), + RESERVED_06( "OPCODE_06", "RESERVED", 6 ), + RESERVED_07( "OPCODE_07", "RESERVED", 7 ), + RESERVED_08( "OPCODE_0B", "RESERVED", 8 ), + RESERVED_09( "OPCODE_0B", "RESERVED", 9 ), + RESERVED_0A( "OPCODE_0B", "RESERVED", 10 ), + RESERVED_0B( "OPCODE_0B", "RESERVED", 11 ), + RESERVED_0C( "OPCODE_0C", "RESERVED", 12 ), + RESERVED_0D( "OPCODE_0D", "RESERVED", 13 ), + RESERVED_0E( "OPCODE_0E", "RESERVED", 14 ), + RESERVED_0F( "OPCODE_0F", "RESERVED", 15 ), + RESERVED_10( "OPCODE_10", "RESERVED", 16 ), + RESERVED_11( "OPCODE_11", "RESERVED", 17 ), + RESERVED_12( "OPCODE_12", "RESERVED", 18 ), + RESERVED_13( "OPCODE_13", "RESERVED", 19 ), + RESERVED_14( "OPCODE_14", "RESERVED", 20 ), + RESERVED_15( "OPCODE_15", "RESERVED", 21 ), + RESERVED_16( "OPCODE_16", "RESERVED", 22 ), + RESERVED_17( "OPCODE_17", "RESERVED", 23 ), + RESERVED_18( "OPCODE_18", "RESERVED", 24 ), + RESERVED_19( "OPCODE_19", "RESERVED", 25 ), + RESERVED_1A( "OPCODE_1A", "RESERVED", 26 ), + RESERVED_1B( "OPCODE_1B", "RESERVED", 27 ), + RESERVED_1C( "OPCODE_1C", "RESERVED", 28 ), + RESERVED_1D( "OPCODE_1D", "RESERVED", 29 ), + RESERVED_1E( "OPCODE_1E", "RESERVED", 30 ), + RESERVED_1F( "OPCODE_1F", "RESERVED", 31 ), + RESERVED_20( "OPCODE_20", "RESERVED", 32 ), + RESERVED_21( "OPCODE_21", "RESERVED", 33 ), + RESERVED_22( "OPCODE_22", "RESERVED", 34 ), + RESERVED_23( "OPCODE_23", "RESERVED", 35 ), + RESERVED_24( "OPCODE_24", "RESERVED", 36 ), + RESERVED_25( "OPCODE_25", "RESERVED", 37 ), + RESERVED_26( "OPCODE_26", "RESERVED", 38 ), + RESERVED_27( "OPCODE_27", "RESERVED", 39 ), + RESERVED_28( "OPCODE_28", "RESERVED", 40 ), + RESERVED_29( "OPCODE_29", "RESERVED", 41 ), + RESERVED_2A( "OPCODE_2A", "RESERVED", 42 ), + RESERVED_2B( "OPCODE_2B", "RESERVED", 43 ), + RESERVED_2C( "OPCODE_2C", "RESERVED", 44 ), + RESERVED_2D( "OPCODE_2D", "RESERVED", 45 ), + RESERVED_2E( "OPCODE_2E", "RESERVED", 46 ), + RESERVED_2F( "OPCODE_2F", "RESERVED", 47 ), + RESERVED_30( "OPCODE_30", "RESERVED", 48 ), + RESERVED_31( "OPCODE_31", "RESERVED", 49 ), + RESERVED_32( "OPCODE_32", "RESERVED", 50 ), + RESERVED_33( "OPCODE_33", "RESERVED", 51 ), + RESERVED_34( "OPCODE_34", "RESERVED", 52 ), + RESERVED_35( "OPCODE_35", "RESERVED", 53 ), + RESERVED_36( "OPCODE_36", "RESERVED", 54 ), + RESERVED_37( "OPCODE_37", "RESERVED", 55 ), + RESERVED_38( "OPCODE_38", "RESERVED", 56 ), + RESERVED_39( "OPCODE_39", "RESERVED", 57 ), + RESERVED_3A( "OPCODE_3A", "RESERVED", 58 ), + RESERVED_3B( "OPCODE_3B", "RESERVED", 59 ), + RESERVED_3C( "OPCODE_3C", "RESERVED", 60 ), + RESERVED_3D( "OPCODE_3D", "RESERVED", 61 ), + RESERVED_3E( "OPCODE_3E", "RESERVED", 62 ), + RESERVED_3F( "OPCODE_3F", "RESERVED", 63 ), + UNKNOWN( "UNKNOWN OPCODE", "UNKNOWN", -1 ); private String mLabel; private String mDescription;