From c579f1617d40cb0c9a29e86a495ae76037a31f58 Mon Sep 17 00:00:00 2001 From: "dennis.sheirer" Date: Wed, 7 Jan 2015 02:15:51 +0000 Subject: [PATCH] P25 work in progress --- src/decode/p25/P25ChannelState.java | 702 ++++++++++++++---- src/decode/p25/P25Interleave.java | 2 +- ...lisHalfRate.java => Trellis_1_2_Rate.java} | 8 +- src/decode/p25/message/hdu/HDUMessage.java | 8 +- src/decode/p25/message/ldu/LDU2Message.java | 60 +- src/decode/p25/message/ldu/LDUMessage.java | 2 +- .../ldu/lc/UnitAuthenticationCommand.java | 23 +- .../ldu/lc/UnitRegistrationCommand.java | 24 +- .../tdu/lc/UnitAuthenticationCommand.java | 25 +- .../tdu/lc/UnitRegistrationCommand.java | 24 +- src/dsp/fsk/P25MessageFramer.java | 4 +- 11 files changed, 704 insertions(+), 178 deletions(-) rename src/decode/p25/{TrellisHalfRate.java => Trellis_1_2_Rate.java} (98%) diff --git a/src/decode/p25/P25ChannelState.java b/src/decode/p25/P25ChannelState.java index c720ba0c..0c90f05d 100644 --- a/src/decode/p25/P25ChannelState.java +++ b/src/decode/p25/P25ChannelState.java @@ -23,10 +23,11 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import message.Message; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import message.Message; import alias.Alias; import alias.AliasList; import audio.SquelchListener; @@ -38,6 +39,10 @@ import controller.channel.ProcessingChain; import controller.state.AuxChannelState; 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.pdu.PDUMessage; import decode.p25.message.pdu.osp.control.CallAlertExtended; import decode.p25.message.pdu.osp.control.GroupAffiliationQueryExtended; @@ -55,6 +60,7 @@ 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.TDULinkControlMessage; import decode.p25.message.tsbk.TSBKMessage; import decode.p25.message.tsbk.osp.control.AcknowledgeResponse; import decode.p25.message.tsbk.osp.control.AuthenticationCommand; @@ -97,6 +103,8 @@ import decode.p25.reference.Vendor; 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; @@ -132,6 +140,9 @@ public class P25ChannelState extends ChannelState super.setSquelchState( SquelchState.UNSQUELCH ); } + /** + * Message processor. All messages are received and processed via this method. + */ public void receive( Message message ) { super.receive( message ); @@ -139,146 +150,540 @@ public class P25ChannelState extends ChannelState if( message instanceof P25Message ) { mActivitySummary.receive( (P25Message)message ); + + if( message instanceof HDUMessage ) + { + /* Header Data Unit Message - preceeds voice LDUs */ + processHDU( (HDUMessage)message ); + } + if( message instanceof LDUMessage ) + { + /* Voice Vocoder messages */ + processLDU( (LDUMessage)message ); + } + else if( message instanceof PDUMessage ) + { + /* Packet Data Unit Messages */ + processPDU( (PDUMessage)message ); + } + else if( message instanceof TDULinkControlMessage ) + { + /* Terminator Data Unit with Link Control Message */ + processTDULC( (TDULinkControlMessage)message ); + } + else if( message instanceof TSBKMessage ) + { + /* Trunking Signalling Block Messages - indicates Control Channel */ + setState( State.CONTROL ); + + processTSBK( (TSBKMessage)message ); + } } + } + + private void processHDU( HDUMessage hdu ) + { - if( message instanceof PDUMessage ) + } + + private void processTDULC( TDULinkControlMessage tdulc ) + { + switch( tdulc.getOpcode() ) { - PDUMessage pdu = (PDUMessage)message; - - switch( pdu.getOpcode() ) + case CALL_ALERT: + decode.p25.message.tdu.lc.CallAlert ca = + (decode.p25.message.tdu.lc.CallAlert)tdulc; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( ca.getSourceAddress() ) + .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: + decode.p25.message.tdu.lc.GroupVoiceChannelUser gvcuser = + (decode.p25.message.tdu.lc.GroupVoiceChannelUser)tdulc; + + if( isActiveCall( CURRENT_CHANNEL, gvcuser.getGroupAddress() ) ) + { + 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() ); + } + } + else + { + CallEvent gvcuserEvent = + new P25CallEvent.Builder( CallEventType.CALL ) + .aliasList( mAliasList ) + .channel( CURRENT_CHANNEL ) + .details( ( gvcuser.isEncrypted() ? "ENCRYPTED" : "" ) + + ( gvcuser.isEmergency() ? " EMERGENCY" : "") ) + .from( gvcuser.getSourceAddress() ) + .to( gvcuser.getGroupAddress() ) + .build(); + + mCallEventModel.add( gvcuserEvent ); + + addCall( gvcuserEvent ); + + setState( State.CALL ); + } + 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() ); + 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() ); + 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() ); + 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() ); + 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() ); + break; + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER: + //TODO: process call + 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() ); + break; + case UNIT_REGISTRATION_COMMAND: + 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() ); + break; + case UNIT_TO_UNIT_ANSWER_REQUEST: + decode.p25.message.tdu.lc.UnitToUnitAnswerRequest uuar = + (decode.p25.message.tdu.lc.UnitToUnitAnswerRequest)tdulc; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( uuar.getSourceAddress() ) + .to( uuar.getTargetAddress() ) + .details( "UNIT TO UNIT CALL ALERT" ) + .build() ); + break; + case UNIT_TO_UNIT_VOICE_CHANNEL_USER: + //TODO: process call here + 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; + } + } + + private void processLDU( LDUMessage ldu ) + { + if( ldu instanceof LDU1Message ) + { + switch( ((LDU1Message)ldu).getOpcode() ) { case CALL_ALERT: - processCall( pdu ); + 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() ); + break; + case CALL_TERMINATION_OR_CANCELLATION: + //TODO: terminate all active calls for this channel state + 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() ); break; case GROUP_AFFILIATION_QUERY: - processQuery( pdu ); + 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() ); break; - case GROUP_AFFILIATION_RESPONSE: - processResponse( pdu ); + case GROUP_VOICE_CHANNEL_UPDATE: + //TODO: process call here break; - case GROUP_DATA_CHANNEL_GRANT: - case GROUP_VOICE_CHANNEL_GRANT: - case INDIVIDUAL_DATA_CHANNEL_GRANT: - processCall( pdu ); + case GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT: + //TODO: process call here + break; + case GROUP_VOICE_CHANNEL_USER: + //TODO: process call here break; case MESSAGE_UPDATE: - processMessage( pdu ); + 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() ); break; - case RFSS_STATUS_BROADCAST: - processRFSSStatus( (RFSSStatusBroadcastExtended)message ); - break; - case ROAMING_ADDRESS_UPDATE: - processResponse( pdu ); + 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() ); break; case STATUS_QUERY: - processQuery( pdu ); + 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() ); break; case STATUS_UPDATE: - processResponse( pdu ); + 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() ); + 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() ); + break; + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_USER: + //TODO: process call + 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() ); + break; + case UNIT_REGISTRATION_COMMAND: + 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() ); break; case UNIT_TO_UNIT_ANSWER_REQUEST: - processPage( pdu ); + decode.p25.message.ldu.lc.UnitToUnitAnswerRequest uuar = + (decode.p25.message.ldu.lc.UnitToUnitAnswerRequest)ldu; + mCallEventModel.add( + new P25CallEvent.Builder( CallEventType.PAGE ) + .aliasList( mAliasList ) + .from( uuar.getSourceAddress() ) + .to( uuar.getTargetAddress() ) + .details( "UNIT TO UNIT CALL ALERT" ) + .build() ); + break; + case UNIT_TO_UNIT_VOICE_CHANNEL_USER: + //TODO: process call here + 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 ) + { + + } + + } + + /** + * Process a Trunking Signalling Block message + */ + private void processTSBK( TSBKMessage tsbk ) + { + if( tsbk.getVendor() == Vendor.STANDARD ) + { + switch( tsbk.getOpcode() ) + { + case ACKNOWLEDGE_RESPONSE: + processTSBKResponse( tsbk ); + break; + case AUTHENTICATION_COMMAND: + processTSBKCommand( tsbk ); + break; + case CALL_ALERT: + processTSBKCall( tsbk ); + break; + case DENY_RESPONSE: + processTSBKResponse( tsbk ); + break; + case EXTENDED_FUNCTION_COMMAND: + processTSBKCommand( tsbk ); + break; + case GROUP_AFFILIATION_QUERY: + processTSBKQuery( tsbk ); + break; + case GROUP_AFFILIATION_RESPONSE: + processTSBKResponse( tsbk ); + break; + case GROUP_DATA_CHANNEL_ANNOUNCEMENT: + case GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT: + case GROUP_DATA_CHANNEL_GRANT: + case GROUP_VOICE_CHANNEL_GRANT: + case GROUP_VOICE_CHANNEL_GRANT_UPDATE: + case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT: + case INDIVIDUAL_DATA_CHANNEL_GRANT: + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: + case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: + case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: + processTSBKCall( tsbk ); + break; + case LOCATION_REGISTRATION_RESPONSE: + case UNIT_DEREGISTRATION_ACKNOWLEDGE: + processTSBKResponse( tsbk ); + break; + case MESSAGE_UPDATE: + processTSBKMessage( tsbk ); + break; + case PROTECTION_PARAMETER_UPDATE: + processTSBKResponse( tsbk ); + break; + case QUEUED_RESPONSE: + processTSBKResponse( tsbk ); + break; + case RADIO_UNIT_MONITOR_COMMAND: + processTSBKCommand( tsbk ); + break; + case RFSS_STATUS_BROADCAST: + processTSBKRFSSStatus( (RFSSStatusBroadcast)tsbk ); + break; + case ROAMING_ADDRESS_COMMAND: + processTSBKCommand( tsbk ); + break; + case SNDCP_DATA_CHANNEL_GRANT: + processTSBKCall( tsbk ); + break; + case STATUS_QUERY: + processTSBKQuery( tsbk ); + break; + case STATUS_UPDATE: + processTSBKResponse( tsbk ); + break; + case TELEPHONE_INTERCONNECT_ANSWER_REQUEST: + case UNIT_TO_UNIT_ANSWER_REQUEST: + processTSBKPage( tsbk ); + break; + case UNIT_REGISTRATION_COMMAND: + processTSBKCommand( tsbk ); break; case UNIT_REGISTRATION_RESPONSE: - processResponse( pdu ); + processTSBKResponse( tsbk ); break; default: break; } } - else if( message instanceof TSBKMessage ) + } + + /** + * Process a Packet Data Unit message + */ + private void processPDU( PDUMessage message ) + { + switch( message.getOpcode() ) { - TSBKMessage tsbk = (TSBKMessage)message; - - setState( State.CONTROL ); - - if( tsbk.getVendor() == Vendor.STANDARD ) - { - switch( tsbk.getOpcode() ) - { - case ACKNOWLEDGE_RESPONSE: - processResponse( tsbk ); - break; - case AUTHENTICATION_COMMAND: - processCommand( tsbk ); - break; - case CALL_ALERT: - processCall( tsbk ); - break; - case DENY_RESPONSE: - processResponse( tsbk ); - break; - case EXTENDED_FUNCTION_COMMAND: - processCommand( tsbk ); - break; - case GROUP_AFFILIATION_QUERY: - processQuery( tsbk ); - break; - case GROUP_AFFILIATION_RESPONSE: - processResponse( tsbk ); - break; - case GROUP_DATA_CHANNEL_ANNOUNCEMENT: - case GROUP_DATA_CHANNEL_ANNOUNCEMENT_EXPLICIT: - case GROUP_DATA_CHANNEL_GRANT: - case GROUP_VOICE_CHANNEL_GRANT: - case GROUP_VOICE_CHANNEL_GRANT_UPDATE: - case GROUP_VOICE_CHANNEL_GRANT_UPDATE_EXPLICIT: - case INDIVIDUAL_DATA_CHANNEL_GRANT: - case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT: - case TELEPHONE_INTERCONNECT_VOICE_CHANNEL_GRANT_UPDATE: - case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT: - case UNIT_TO_UNIT_VOICE_CHANNEL_GRANT_UPDATE: - processCall( tsbk ); - break; - case LOCATION_REGISTRATION_RESPONSE: - case UNIT_DEREGISTRATION_ACKNOWLEDGE: - processResponse( tsbk ); - break; - case MESSAGE_UPDATE: - processMessage( tsbk ); - break; - case PROTECTION_PARAMETER_UPDATE: - processResponse( tsbk ); - break; - case QUEUED_RESPONSE: - processResponse( tsbk ); - break; - case RADIO_UNIT_MONITOR_COMMAND: - processCommand( tsbk ); - break; - case RFSS_STATUS_BROADCAST: - processRFSSStatus( (RFSSStatusBroadcast)tsbk ); - break; - case ROAMING_ADDRESS_COMMAND: - processCommand( tsbk ); - break; - case SNDCP_DATA_CHANNEL_GRANT: - processCall( tsbk ); - break; - case STATUS_QUERY: - processQuery( tsbk ); - break; - case STATUS_UPDATE: - processResponse( tsbk ); - break; - case TELEPHONE_INTERCONNECT_ANSWER_REQUEST: - case UNIT_TO_UNIT_ANSWER_REQUEST: - processPage( tsbk ); - break; - case UNIT_REGISTRATION_COMMAND: - processCommand( tsbk ); - break; - case UNIT_REGISTRATION_RESPONSE: - processResponse( tsbk ); - break; - default: - break; - } - } + 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; } } - private void processCommand( TSBKMessage message ) + private void processTSBKCommand( TSBKMessage message ) { CallEvent event = null; @@ -376,7 +781,7 @@ public class P25ChannelState extends ChannelState } } - private void processMessage( TSBKMessage message ) + private void processTSBKMessage( TSBKMessage message ) { MessageUpdate mu = (MessageUpdate)message; @@ -407,7 +812,7 @@ public class P25ChannelState extends ChannelState mCallEventModel.add( event ); } - private void processQuery( TSBKMessage message ) + private void processTSBKQuery( TSBKMessage message ) { CallEvent event = null; @@ -504,7 +909,7 @@ public class P25ChannelState extends ChannelState } } - private void processResponse( TSBKMessage message ) + private void processTSBKResponse( TSBKMessage message ) { CallEvent event = null; @@ -839,7 +1244,7 @@ public class P25ChannelState extends ChannelState } } - private void processRFSSStatus( RFSSStatusBroadcast message ) + private void processTSBKRFSSStatus( RFSSStatusBroadcast message ) { if( mNAC == null || !mNAC.contentEquals( message.getNAC() ) ) { @@ -907,7 +1312,7 @@ public class P25ChannelState extends ChannelState } } - private void processCall( PDUMessage message ) + private void processPDUCall( PDUMessage message ) { switch( message.getOpcode() ) { @@ -915,7 +1320,7 @@ public class P25ChannelState extends ChannelState CallAlertExtended ca = (CallAlertExtended)message; mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.CALL_ALERT ) + new P25CallEvent.Builder( CallEventType.PAGE ) .aliasList( mAliasList ) .from( ca.getWACN() + "-" + ca.getSystemID() + "-" + ca.getSourceID() ) @@ -928,7 +1333,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdcge.getTransmitChannel(), gdcge.getGroupAddress() ) ) { - updateCall( gdcge.getTransmitChannel(), gdcge.getGroupAddress() ); + updateCall( gdcge.getTransmitChannel(), null, gdcge.getGroupAddress() ); } else { @@ -954,7 +1359,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gvcge.getTransmitChannel(), gvcge.getGroupAddress() ) ) { - updateCall( gvcge.getTransmitChannel(), gvcge.getGroupAddress() ); + updateCall( gvcge.getTransmitChannel(), null, gvcge.getGroupAddress() ); } else { @@ -980,7 +1385,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( idcge.getTransmitChannel(), idcge.getTargetAddress() ) ) { - updateCall( idcge.getTransmitChannel(), idcge.getTargetAddress() ); + updateCall( idcge.getTransmitChannel(), null, idcge.getTargetAddress() ); } else { @@ -1008,7 +1413,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( ticge.getTransmitChannel(), ticge.getAddress() )) { - updateCall( ticge.getTransmitChannel(), ticge.getAddress() ); + updateCall( ticge.getTransmitChannel(), null, ticge.getAddress() ); } else { @@ -1034,7 +1439,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcge.getTransmitChannel(), uuvcge.getTargetAddress() ) ) { - updateCall( uuvcge.getTransmitChannel(), uuvcge.getTargetAddress() ); + updateCall( uuvcge.getTransmitChannel(), null, uuvcge.getTargetAddress() ); } else { @@ -1063,7 +1468,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcgue.getTransmitChannel(), uuvcgue.getTargetAddress() ) ) { - updateCall( uuvcgue.getTransmitChannel(), + updateCall( uuvcgue.getTransmitChannel(), null, uuvcgue.getTargetAddress() ); } else @@ -1097,7 +1502,7 @@ public class P25ChannelState extends ChannelState /** * Process a call event message */ - private void processCall( TSBKMessage message ) + private void processTSBKCall( TSBKMessage message ) { switch( message.getOpcode() ) { @@ -1105,7 +1510,7 @@ public class P25ChannelState extends ChannelState CallAlert ca = (CallAlert)message; mCallEventModel.add( - new P25CallEvent.Builder( CallEventType.CALL_ALERT ) + new P25CallEvent.Builder( CallEventType.PAGE ) .aliasList( mAliasList ) .from( ca.getSourceID() ) .to( ca.getTargetAddress() ) @@ -1116,7 +1521,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdca.getChannel1(), gdca.getGroupAddress1() ) ) { - updateCall( gdca.getChannel1(), gdca.getGroupAddress1() ); + updateCall( gdca.getChannel1(), null, gdca.getGroupAddress1() ); } else { @@ -1139,7 +1544,7 @@ public class P25ChannelState extends ChannelState { if( isActiveCall( gdca.getChannel2(), gdca.getGroupAddress2() ) ) { - updateCall( gdca.getChannel2(), gdca.getGroupAddress2() ); + updateCall( gdca.getChannel2(), null, gdca.getGroupAddress2() ); } else { @@ -1165,7 +1570,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdcae.getTransmitChannel(), gdcae.getGroupAddress() ) ) { - updateCall( gdcae.getTransmitChannel(), gdcae.getGroupAddress() ); + updateCall( gdcae.getTransmitChannel(), null, gdcae.getGroupAddress() ); } else { @@ -1189,7 +1594,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gdcg.getChannel(), gdcg.getGroupAddress() ) ) { - updateCall( gdcg.getChannel(), gdcg.getGroupAddress() ); + updateCall( gdcg.getChannel(), null, gdcg.getGroupAddress() ); } else { @@ -1214,7 +1619,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gvcg.getChannel(), gvcg.getGroupAddress() ) ) { - updateCall( gvcg.getChannel(), gvcg.getGroupAddress() ); + updateCall( gvcg.getChannel(), null, gvcg.getGroupAddress() ); } else { @@ -1240,7 +1645,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( gvcgu.getChannel1(), gvcgu.getGroupAddress1() ) ) { - updateCall( gvcgu.getChannel1(), gvcgu.getGroupAddress1() ); + updateCall( gvcgu.getChannel1(), null, gvcgu.getGroupAddress1() ); } else { @@ -1263,7 +1668,7 @@ public class P25ChannelState extends ChannelState { if( isActiveCall( gvcgu.getChannel2(), gvcgu.getGroupAddress2() ) ) { - updateCall( gvcgu.getChannel2(), gvcgu.getGroupAddress2() ); + updateCall( gvcgu.getChannel2(), null, gvcgu.getGroupAddress2() ); } else { @@ -1303,7 +1708,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( idcg.getChannel(), idcg.getTargetAddress() ) ) { - updateCall( idcg.getChannel(), idcg.getTargetAddress() ); + updateCall( idcg.getChannel(), null, idcg.getTargetAddress() ); } else { @@ -1328,7 +1733,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( sdcg.getTransmitChannel(), sdcg.getTargetAddress() ) ) { - updateCall( sdcg.getTransmitChannel(), sdcg.getTargetAddress() ); + updateCall( sdcg.getTransmitChannel(), null, sdcg.getTargetAddress() ); } else { @@ -1352,7 +1757,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( tivcg.getChannel(), tivcg.getAddress() )) { - updateCall( tivcg.getChannel(), tivcg.getAddress() ); + updateCall( tivcg.getChannel(), null, tivcg.getAddress() ); } else { @@ -1378,7 +1783,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( tivcgu.getChannel(), tivcgu.getAddress() ) ) { - updateCall( tivcgu.getChannel(), tivcgu.getAddress() ); + updateCall( tivcgu.getChannel(), null, tivcgu.getAddress() ); } else { @@ -1404,7 +1809,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcg.getChannel(), uuvcg.getTargetAddress() ) ) { - updateCall( uuvcg.getChannel(), uuvcg.getTargetAddress() ); + updateCall( uuvcg.getChannel(), null, uuvcg.getTargetAddress() ); } else { @@ -1432,7 +1837,7 @@ public class P25ChannelState extends ChannelState if( isActiveCall( uuvcgu.getChannel(), uuvcgu.getTargetAddress() ) ) { - updateCall( uuvcgu.getChannel(), uuvcgu.getTargetAddress() ); + updateCall( uuvcgu.getChannel(), null, uuvcgu.getTargetAddress() ); } else { @@ -1478,14 +1883,22 @@ public class P25ChannelState extends ChannelState .getResourceManager().getThreadPoolManager(), event ) ); } - private void updateCall( String channel, String id ) + private void updateCall( String channel, String fromID, String toID ) { for( ActiveCall call: mActiveCalls ) { - if( call.matches( channel, id ) ) + if( call.matches( channel, toID ) ) { call.update( System.currentTimeMillis() ); + setState( getState() ); + + if( fromID != null && + !call.getCallEvent().getFromID().contentEquals( fromID ) ) + { + call.getCallEvent().setFromID( fromID ); + } + return; } } @@ -1494,7 +1907,7 @@ public class P25ChannelState extends ChannelState /** * Process a unit paging event message */ - private void processPage( TSBKMessage message ) + private void processTSBKPage( TSBKMessage message ) { CallEvent event = null; @@ -1683,6 +2096,11 @@ public class P25ChannelState extends ChannelState { mCallEventModel.setEnd( mEvent ); mActiveCalls.remove( this ); + +// if( mEvent.getChannel().contentEquals( CURRENT_CHANNEL ) ) +// { +// setState( State.IDLE ); +// } } else { diff --git a/src/decode/p25/P25Interleave.java b/src/decode/p25/P25Interleave.java index 8d70ecd4..5190ddbe 100644 --- a/src/decode/p25/P25Interleave.java +++ b/src/decode/p25/P25Interleave.java @@ -140,7 +140,7 @@ public class P25Interleave public static void main( String[] args ) { - TrellisHalfRate halfrate = new TrellisHalfRate(); + Trellis_1_2_Rate halfrate = new Trellis_1_2_Rate(); int start = 0; int end = 196; diff --git a/src/decode/p25/TrellisHalfRate.java b/src/decode/p25/Trellis_1_2_Rate.java similarity index 98% rename from src/decode/p25/TrellisHalfRate.java rename to src/decode/p25/Trellis_1_2_Rate.java index 249b09da..a9f47899 100644 --- a/src/decode/p25/TrellisHalfRate.java +++ b/src/decode/p25/Trellis_1_2_Rate.java @@ -9,12 +9,12 @@ import org.slf4j.LoggerFactory; import bits.BitSetBuffer; import dsp.fsk.Dibit; -public class TrellisHalfRate +public class Trellis_1_2_Rate { public final static int MAX_ERROR_THRESHOLD = 7; private final static Logger mLog = - LoggerFactory.getLogger( TrellisHalfRate.class ); + LoggerFactory.getLogger( Trellis_1_2_Rate.class ); private ArrayList mConstellationNodes = new ArrayList(); @@ -37,7 +37,7 @@ public class TrellisHalfRate { 3,4,2,3,2,3,1,2,2,3,1,2,1,2,0,1 }, { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 } }; - public TrellisHalfRate() + public Trellis_1_2_Rate() { /* Create 49 x 4-bit constellation nodes to handle 196-bit blocks */ ConstellationNode previous = null; @@ -525,7 +525,7 @@ public class TrellisHalfRate mLog.debug( " BUFFER: " + buffer.toString() ); - TrellisHalfRate t = new TrellisHalfRate(); + Trellis_1_2_Rate t = new Trellis_1_2_Rate(); t.decode( buffer, 0, 196 ); mLog.debug( " DECODED: " + buffer.toString() ); diff --git a/src/decode/p25/message/hdu/HDUMessage.java b/src/decode/p25/message/hdu/HDUMessage.java index e8c249ed..b3977b06 100644 --- a/src/decode/p25/message/hdu/HDUMessage.java +++ b/src/decode/p25/message/hdu/HDUMessage.java @@ -60,7 +60,11 @@ public class HDUMessage extends P25Message sb.append( " ENCRYPTION:" ); sb.append( encryption.name() ); sb.append( " KEY ID:" + getKeyID() ); - sb.append( " IV:" + getEncryptionInitializationVector() ); + sb.append( " MSG INDICATOR:" + getMessageIndicator() ); + } + else + { + sb.append( " UNENCRYPTED" ); } sb.append( " " ); @@ -69,7 +73,7 @@ public class HDUMessage extends P25Message return sb.toString(); } - public String getEncryptionInitializationVector() + public String getMessageIndicator() { StringBuilder sb = new StringBuilder(); diff --git a/src/decode/p25/message/ldu/LDU2Message.java b/src/decode/p25/message/ldu/LDU2Message.java index dccf186a..c345dc57 100644 --- a/src/decode/p25/message/ldu/LDU2Message.java +++ b/src/decode/p25/message/ldu/LDU2Message.java @@ -2,12 +2,32 @@ package decode.p25.message.ldu; import alias.AliasList; import bits.BitSetBuffer; -import decode.p25.message.P25Message; import decode.p25.reference.DataUnitID; +import decode.p25.reference.Encryption; import edac.CRC; public class LDU2Message extends LDUMessage { +// public static final int[] OCTET_0 = { 352,353,354,355,356,357,362,363 }; +// public static final int[] OCTET_1 = { 364,365,366,367,372,373,374,375 }; +// public static final int[] OCTET_2 = { 376,377,382,383,384,385,386,387 }; +// public static final int[] OCTET_3 = { 536,537,538,539,540,541,546,547 }; +// public static final int[] OCTET_4 = { 548,549,550,551,556,557,558,559 }; +// public static final int[] OCTET_5 = { 560,561,566,567,568,569,570,571 }; +// public static final int[] OCTET_6 = { 720,721,722,723,724,725,730,731 }; +// public static final int[] OCTET_7 = { 732,733,734,735,740,741,742,743 }; +// public static final int[] OCTET_8 = { 744,745,750,751,752,753,754,755 }; + + public static final int[] MESSAGE_INDICATOR_A = { 352,353,354,355,356,357, + 362,363,364,365,366,367,372,373,374,375,376,377,382,383,384,385,386,387, + 536,537,538,539,540,541,546,547,548,549,550,551 }; + public static final int[] MESSAGE_INDICATOR_B = { 556,557,558,559,560,561, + 566,567,568,569,570,571,720,721,722,723,724,725,730,731,732,733,734,735, + 740,741,742,743,744,745,750,751,752,753,754,755 }; + public static final int[] ALGORITHM_ID = { 904,905,906,907,908,909,914,915 }; + public static final int[] KEY_ID = { 916,917,918,919,924,925,926,927,928, + 929,934,935,936,937,938,939 }; + public LDU2Message( BitSetBuffer message, DataUnitID duid, AliasList aliasList ) { @@ -25,8 +45,22 @@ public class LDU2Message extends LDUMessage StringBuilder sb = new StringBuilder(); sb.append( super.getMessageStub() ); - sb.append( " " ); + Encryption encryption = getEncryption(); + + if( encryption != Encryption.UNENCRYPTED ) + { + sb.append( "ENCRYPTION:" ); + sb.append( encryption.name() ); + sb.append( " KEY ID:" + getKeyID() ); + sb.append( " MSG INDICATOR:" + getMessageIndicator() ); + } + else + { + sb.append( "UNENCRYPTED" ); + } + + sb.append( " " ); sb.append( mMessage.toString() ); return sb.toString(); @@ -37,5 +71,27 @@ public class LDU2Message extends LDUMessage { return true; } + + public String getMessageIndicator() + { + StringBuilder sb = new StringBuilder(); + + sb.append( mMessage.getHex( MESSAGE_INDICATOR_A, 9 ) ); + sb.append( mMessage.getHex( MESSAGE_INDICATOR_B, 9 ) ); + + return sb.toString(); + } + + public Encryption getEncryption() + { + return Encryption.fromValue( mMessage.getInt( ALGORITHM_ID ) ); + } + + public int getKeyID() + { + return mMessage.getInt( KEY_ID ); + } + + } diff --git a/src/decode/p25/message/ldu/LDUMessage.java b/src/decode/p25/message/ldu/LDUMessage.java index 2941ca91..d7aa682f 100644 --- a/src/decode/p25/message/ldu/LDUMessage.java +++ b/src/decode/p25/message/ldu/LDUMessage.java @@ -49,7 +49,7 @@ public class LDUMessage extends P25Message sb.append( getNAC() ); sb.append( " " ); sb.append( getDUID().getLabel() ); - sb.append( " LSD:" ); + sb.append( " VOICE LSD:" ); sb.append( getLowSpeedData() ); sb.append( " " ); diff --git a/src/decode/p25/message/ldu/lc/UnitAuthenticationCommand.java b/src/decode/p25/message/ldu/lc/UnitAuthenticationCommand.java index 1bdf3898..2e0cf1e2 100644 --- a/src/decode/p25/message/ldu/lc/UnitAuthenticationCommand.java +++ b/src/decode/p25/message/ldu/lc/UnitAuthenticationCommand.java @@ -14,7 +14,7 @@ public class UnitAuthenticationCommand extends LDU1Message 376,377,382,383,384,385,386,387,536,537,538,539 }; public static final int[] SYSTEM_ID = { 540,541,546,547,548,549,550,551,556, 557,558,559 }; - public static final int[] SOURCE_ID = { 560,561,566,567,568,569,570,571,720, + public static final int[] TARGET_ID = { 560,561,566,567,568,569,570,571,720, 721,722,723,724,725,730,731,732,733,734,735,740,741,742,743 }; public UnitAuthenticationCommand( LDU1Message message ) @@ -35,9 +35,20 @@ public class UnitAuthenticationCommand extends LDU1Message sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); - sb.append( " ID:" + getSourceID() ); + sb.append( " ADDRESS:" + getCompleteTargetAddress() ); + + return sb.toString(); + } + + public String getCompleteTargetAddress() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getNetworkID() ); + sb.append( ":" ); + sb.append( getSystemID() ); + sb.append( ":" ); + sb.append( getTargetID() ); return sb.toString(); } @@ -52,8 +63,8 @@ public class UnitAuthenticationCommand extends LDU1Message return mMessage.getHex( SYSTEM_ID, 3 ); } - public String getSourceID() + public String getTargetID() { - return mMessage.getHex( SOURCE_ID, 6 ); + return mMessage.getHex( TARGET_ID, 6 ); } } diff --git a/src/decode/p25/message/ldu/lc/UnitRegistrationCommand.java b/src/decode/p25/message/ldu/lc/UnitRegistrationCommand.java index 4506430f..50c2b559 100644 --- a/src/decode/p25/message/ldu/lc/UnitRegistrationCommand.java +++ b/src/decode/p25/message/ldu/lc/UnitRegistrationCommand.java @@ -14,7 +14,7 @@ public class UnitRegistrationCommand extends LDU1Message 376,377,382,383,384,385,386,387,536,537,538,539 }; public static final int[] SYSTEM_ID = { 540,541,546,547,548,549,550,551,556, 557,558,559 }; - public static final int[] SOURCE_ID = { 560,561,566,567,568,569,570,571,720, + public static final int[] TARGET_ID = { 560,561,566,567,568,569,570,571,720, 721,722,723,724,725,730,731,732,733,734,735,740,741,742,743 }; public UnitRegistrationCommand( LDU1Message message ) @@ -35,13 +35,25 @@ public class UnitRegistrationCommand extends LDU1Message sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); - sb.append( " ID:" + getSourceID() ); + sb.append( " ADDRESS:" + getCompleteTargetAddress() ); return sb.toString(); } + public String getCompleteTargetAddress() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getNetworkID() ); + sb.append( ":" ); + sb.append( getSystemID() ); + sb.append( ":" ); + sb.append( getTargetID() ); + + return sb.toString(); + } + + public String getNetworkID() { return mMessage.getHex( NETWORK_ID, 5 ); @@ -52,8 +64,8 @@ public class UnitRegistrationCommand extends LDU1Message return mMessage.getHex( SYSTEM_ID, 3 ); } - public String getSourceID() + public String getTargetID() { - return mMessage.getHex( SOURCE_ID, 6 ); + return mMessage.getHex( TARGET_ID, 6 ); } } diff --git a/src/decode/p25/message/tdu/lc/UnitAuthenticationCommand.java b/src/decode/p25/message/tdu/lc/UnitAuthenticationCommand.java index b0138bf3..96af11b2 100644 --- a/src/decode/p25/message/tdu/lc/UnitAuthenticationCommand.java +++ b/src/decode/p25/message/tdu/lc/UnitAuthenticationCommand.java @@ -13,7 +13,9 @@ public class UnitAuthenticationCommand extends TDULinkControlMessage 95,96,97,98,99,112,113,114,115 }; public static final int[] SYSTEM_ID = { 116,117,118,119,120,121,122,123, 136,137,138,139 }; - public static final int[] SOURCE_ID = { 140,141,142,143,144,145,146,147, + /* ICD says this is a source id, but this is a command messages, so this + * must be a target id */ + public static final int[] TARGET_ID = { 140,141,142,143,144,145,146,147, 160,161,162,163,164,165,166,167,168,169,170,171,184,185,186,187 }; public UnitAuthenticationCommand( TDULinkControlMessage source ) @@ -34,9 +36,20 @@ public class UnitAuthenticationCommand extends TDULinkControlMessage sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); - sb.append( " ID:" + getSourceID() ); + sb.append( " ADDRESS:" + getCompleteTargetAddress() ); + + return sb.toString(); + } + + public String getCompleteTargetAddress() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getNetworkID() ); + sb.append( ":" ); + sb.append( getSystemID() ); + sb.append( ":" ); + sb.append( getTargetID() ); return sb.toString(); } @@ -51,8 +64,8 @@ public class UnitAuthenticationCommand extends TDULinkControlMessage return mMessage.getHex( SYSTEM_ID, 3 ); } - public String getSourceID() + public String getTargetID() { - return mMessage.getHex( SOURCE_ID, 6 ); + return mMessage.getHex( TARGET_ID, 6 ); } } diff --git a/src/decode/p25/message/tdu/lc/UnitRegistrationCommand.java b/src/decode/p25/message/tdu/lc/UnitRegistrationCommand.java index 9759f082..6b8e4e2c 100644 --- a/src/decode/p25/message/tdu/lc/UnitRegistrationCommand.java +++ b/src/decode/p25/message/tdu/lc/UnitRegistrationCommand.java @@ -13,7 +13,8 @@ public class UnitRegistrationCommand extends TDULinkControlMessage 95,96,97,98,99,112,113,114,115 }; public static final int[] SYSTEM_ID = { 116,117,118,119,120,121,122,123, 136,137,138,139 }; - public static final int[] SOURCE_ID = { 140,141,142,143,144,145,146,147, + /* ICD calls this source, but should be target address */ + public static final int[] TARGET_ID = { 140,141,142,143,144,145,146,147, 160,161,162,163,164,165,166,167,168,169,170,171,184,185,186,187 }; public UnitRegistrationCommand( TDULinkControlMessage source ) @@ -34,9 +35,20 @@ public class UnitRegistrationCommand extends TDULinkControlMessage sb.append( getMessageStub() ); - sb.append( " NETWORK:" + getNetworkID() ); - sb.append( " SYS:" + getSystemID() ); - sb.append( " ID:" + getSourceID() ); + sb.append( " ADDRESS:" + getCompleteTargetAddress() ); + + return sb.toString(); + } + + public String getCompleteTargetAddress() + { + StringBuilder sb = new StringBuilder(); + + sb.append( getNetworkID() ); + sb.append( ":" ); + sb.append( getSystemID() ); + sb.append( ":" ); + sb.append( getTargetID() ); return sb.toString(); } @@ -51,8 +63,8 @@ public class UnitRegistrationCommand extends TDULinkControlMessage return mMessage.getHex( SYSTEM_ID, 3 ); } - public String getSourceID() + public String getTargetID() { - return mMessage.getHex( SOURCE_ID, 6 ); + return mMessage.getHex( TARGET_ID, 6 ); } } diff --git a/src/dsp/fsk/P25MessageFramer.java b/src/dsp/fsk/P25MessageFramer.java index 2a02840b..93159b5a 100644 --- a/src/dsp/fsk/P25MessageFramer.java +++ b/src/dsp/fsk/P25MessageFramer.java @@ -13,7 +13,7 @@ import bits.BitSetBuffer; import bits.BitSetFullException; import bits.SyncPatternMatcher; import decode.p25.P25Interleave; -import decode.p25.TrellisHalfRate; +import decode.p25.Trellis_1_2_Rate; import decode.p25.message.P25Message; import decode.p25.message.hdu.HDUMessage; import decode.p25.message.ldu.LDU1Message; @@ -60,7 +60,7 @@ public class P25MessageFramer implements Listener private AliasList mAliasList; private SyncPatternMatcher mMatcher; private boolean mInverted = false; - private TrellisHalfRate mHalfRate = new TrellisHalfRate(); + private Trellis_1_2_Rate mHalfRate = new Trellis_1_2_Rate(); private BCH_63_16_11 mNIDDecoder = new BCH_63_16_11(); /**