Revert "Merges master onto development branch"

This reverts commit 2420bc901c63ad9d41e7c99ac95a426f826182ff.
This commit is contained in:
denny
2016-02-13 14:14:54 -05:00
parent 3f674c0b8f
commit 1d7f255784
60 changed files with 2106 additions and 2750 deletions

View File

@@ -42,8 +42,6 @@ import module.decode.p25.message.ldu.lc.TelephoneInterconnectVoiceChannelUser;
import module.decode.p25.message.ldu.lc.UnitToUnitVoiceChannelUser;
import module.decode.p25.message.pdu.PDUMessage;
import module.decode.p25.message.pdu.confirmed.PDUConfirmedMessage;
import module.decode.p25.message.pdu.confirmed.PDUTypeUnknown;
import module.decode.p25.message.pdu.confirmed.PacketData;
import module.decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextAccept;
import module.decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextReject;
import module.decode.p25.message.pdu.confirmed.SNDCPActivateTDSContextRequest;
@@ -120,6 +118,7 @@ import module.decode.p25.message.tsbk.osp.voice.UnitToUnitVoiceChannelGrantUpdat
import module.decode.p25.reference.IPProtocol;
import module.decode.p25.reference.LinkControlOpcode;
import module.decode.p25.reference.Response;
import module.decode.p25.reference.Service;
import module.decode.p25.reference.Vendor;
import module.decode.state.ChangedAttribute;
import module.decode.state.DecoderState;
@@ -407,12 +406,12 @@ public class P25DecoderState extends DecoderState
{
if( hdu.isValid() )
{
broadcast( new DecoderStateEvent( this, Event.START, State.CALL ) );
State state = hdu.isEncrypted() ? State.ENCRYPTED : State.CALL;
broadcast( new DecoderStateEvent( this, Event.START, state ) );
String to = hdu.getToID();
updateTo( to );
if( mCurrentCallEvent == null )
{
mCurrentCallEvent = new P25CallEvent.Builder( CallEventType.CALL )
@@ -426,6 +425,7 @@ public class P25DecoderState extends DecoderState
broadcast( mCurrentCallEvent );
}
updateTo( to );
}
}
@@ -437,7 +437,7 @@ public class P25DecoderState extends DecoderState
{
if( tdulc.getOpcode() == LinkControlOpcode.CALL_TERMINATION_OR_CANCELLATION )
{
broadcast( new DecoderStateEvent( this, Event.END, State.FADE ) );
broadcast( new DecoderStateEvent( this, Event.END, State.END ) );
if( mCurrentCallEvent != null )
{
@@ -615,14 +615,12 @@ public class P25DecoderState extends DecoderState
module.decode.p25.message.tdu.lc.GroupVoiceChannelUser gvcuser =
(module.decode.p25.message.tdu.lc.GroupVoiceChannelUser)tdulc;
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.CALL ) );
broadcast( new DecoderStateEvent( this, Event.CONTINUATION,
( gvcuser.isEncrypted() ? State.ENCRYPTED : State.CALL ) ) );
String from = gvcuser.getSourceAddress();
String to = gvcuser.getGroupAddress();
updateFrom( from );
updateTo( to );
if( mCurrentCallEvent == null )
{
mCurrentCallEvent = new P25CallEvent.Builder( CallEventType.GROUP_CALL )
@@ -638,6 +636,9 @@ public class P25DecoderState extends DecoderState
broadcast( mCurrentCallEvent );
}
updateFrom( from );
updateTo( to );
}
break;
case MESSAGE_UPDATE:
@@ -844,8 +845,6 @@ public class P25DecoderState extends DecoderState
String to = tivcu.getAddress();
updateTo( to );
if( mCurrentCallEvent == null )
{
mCurrentCallEvent = new P25CallEvent.Builder( CallEventType.TELEPHONE_INTERCONNECT )
@@ -859,6 +858,8 @@ public class P25DecoderState extends DecoderState
broadcast( mCurrentCallEvent );
}
updateTo( to );
}
break;
case UNIT_AUTHENTICATION_COMMAND:
@@ -921,10 +922,7 @@ public class P25DecoderState extends DecoderState
(module.decode.p25.message.tdu.lc.UnitToUnitVoiceChannelUser)tdulc;
String from = uuvcu.getSourceAddress();
updateFrom( from );
String to = uuvcu.getTargetAddress();
updateTo( to );
if( mCurrentCallEvent != null )
{
@@ -938,6 +936,9 @@ public class P25DecoderState extends DecoderState
.to( to )
.build();
}
updateFrom( from );
updateTo( to );
}
break;
default:
@@ -949,14 +950,35 @@ public class P25DecoderState extends DecoderState
* 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 message )
private void logAlternateVendorMessage( P25Message p25 )
{
// if( message.isValid() )
// if( p25 instanceof TDULinkControlMessage )
// {
// mLog.info( "PLEASE NOTIFY DEVELOPER - UNRECOGNIZED P25 VENDOR FORMAT -"
// + " DUID:" + message.getDUID()
// + " MSG:" + message.getBinaryMessage()
// + " CLASS:" + message.getClass() );
// 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() + "]" );
// }
}
@@ -967,11 +989,15 @@ public class P25DecoderState extends DecoderState
*/
private void processLDU( LDUMessage ldu )
{
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.CALL ) );
State state = ( ldu.isValid() && ldu.isEncrypted() ) ?
State.ENCRYPTED : State.CALL;
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, state ) );
if( mCurrentCallEvent == null )
{
mCurrentCallEvent = new P25CallEvent.Builder( CallEventType.CALL )
mCurrentCallEvent = new P25CallEvent.Builder(
( state == State.CALL ) ? CallEventType.CALL : CallEventType.ENCRYPTED_CALL )
.aliasList( getAliasList() )
.channel( mCurrentChannel )
.frequency( mCurrentChannelFrequency )
@@ -1031,7 +1057,7 @@ public class P25DecoderState extends DecoderState
}
break;
case CALL_TERMINATION_OR_CANCELLATION:
broadcast( new DecoderStateEvent( this, Event.END, State.FADE ) );
broadcast( new DecoderStateEvent( this, Event.END, State.END ) );
mCurrentCallEvent = null;
if( !( ldu instanceof CallTermination ) )
@@ -1089,43 +1115,42 @@ public class P25DecoderState extends DecoderState
}
break;
case GROUP_VOICE_CHANNEL_UPDATE:
if( ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdate )
if( mChannelType == ChannelType.STANDARD &&
ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdate )
{
module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdate gvcu =
(module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdate)ldu;
(module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdate)ldu;
String userA = gvcu.getGroupAddressA();
if( !mCallDetectTalkgroups.contains( userA ) )
{
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcu.getChannelA() )
.details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcu.getDownlinkFrequencyA() )
.to( userA )
.build() );
mCallDetectTalkgroups.add( userA );
}
String userB = gvcu.getGroupAddressB();
if( mChannelType == ChannelType.STANDARD )
if( userB != null &&
!userB.contentEquals( "0000" ) &&
!mCallDetectTalkgroups.contains( userB ) )
{
if( !mCallDetectTalkgroups.contains( userA ) )
{
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcu.getChannelA() )
.details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcu.getDownlinkFrequencyA() )
.to( userA )
.build() );
mCallDetectTalkgroups.add( userA );
}
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcu.getChannelB() )
.details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcu.getDownlinkFrequencyB() )
.to( userB )
.build() );
if( userB != null &&
!userB.contentEquals( "0000" ) &&
!mCallDetectTalkgroups.contains( userB ) )
{
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcu.getChannelB() )
.details( ( gvcu.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcu.getDownlinkFrequencyB() )
.to( userB )
.build() );
mCallDetectTalkgroups.add( userB );
}
mCallDetectTalkgroups.add( userB );
}
}
else
@@ -1134,27 +1159,25 @@ public class P25DecoderState extends DecoderState
}
break;
case GROUP_VOICE_CHANNEL_UPDATE_EXPLICIT:
if( ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit )
if( mChannelType == ChannelType.STANDARD &&
ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit )
{
module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit gvcue =
(module.decode.p25.message.ldu.lc.GroupVoiceChannelUpdateExplicit)ldu;
String group = gvcue.getGroupAddress();
if( mChannelType == ChannelType.STANDARD )
if( !mCallDetectTalkgroups.contains( group ) )
{
if( !mCallDetectTalkgroups.contains( group ) )
{
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcue.getTransmitChannel() )
.details( ( gvcue.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcue.getDownlinkFrequency() )
.to( group )
.build() );
mCallDetectTalkgroups.add( group );
}
broadcast( new P25CallEvent.Builder( CallEventType.CALL_DETECT )
.aliasList( getAliasList() )
.channel( gvcue.getTransmitChannel() )
.details( ( gvcue.isEncrypted() ? "ENCRYPTED" : "" ) )
.frequency( gvcue.getDownlinkFrequency() )
.to( group )
.build() );
mCallDetectTalkgroups.add( group );
}
}
else
@@ -1164,32 +1187,29 @@ public class P25DecoderState extends DecoderState
break;
case GROUP_VOICE_CHANNEL_USER:
/* Indicates the current user of the current channel */
if( ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUser )
if( mChannelType == ChannelType.STANDARD &&
ldu instanceof module.decode.p25.message.ldu.lc.GroupVoiceChannelUser )
{
module.decode.p25.message.ldu.lc.GroupVoiceChannelUser gvcuser =
(module.decode.p25.message.ldu.lc.GroupVoiceChannelUser)ldu;
updateFrom( gvcuser.getSourceAddress() );
updateTo( gvcuser.getGroupAddress() );
if( mChannelType == ChannelType.STANDARD )
if( mCurrentCallEvent.getCallEventType() != CallEventType.GROUP_CALL )
{
if( mCurrentCallEvent.getCallEventType() != CallEventType.GROUP_CALL )
{
mCurrentCallEvent.setCallEventType( CallEventType.GROUP_CALL );
broadcast( mCurrentCallEvent );
}
if( mCurrentCallEvent.getDetails() == null )
{
mCurrentCallEvent.setDetails(
( gvcuser.isEncrypted() ? "ENCRYPTED " : "" ) +
( gvcuser.isEmergency() ? "EMERGENCY " : "" ) );
broadcast( mCurrentCallEvent );
}
mCurrentCallEvent.setCallEventType( CallEventType.GROUP_CALL );
broadcast( mCurrentCallEvent );
}
if( mCurrentCallEvent.getDetails() == null )
{
mCurrentCallEvent.setDetails(
( gvcuser.isEncrypted() ? "ENCRYPTED " : "" ) +
( gvcuser.isEmergency() ? "EMERGENCY " : "" ) );
broadcast( mCurrentCallEvent );
}
updateFrom( gvcuser.getSourceAddress() );
updateTo( gvcuser.getGroupAddress() );
}
else
{
@@ -1385,8 +1405,6 @@ public class P25DecoderState extends DecoderState
TelephoneInterconnectVoiceChannelUser tivcu =
(TelephoneInterconnectVoiceChannelUser)ldu;
updateTo( tivcu.getAddress() );
if( mCurrentCallEvent.getCallEventType() != CallEventType.TELEPHONE_INTERCONNECT )
{
mCurrentCallEvent.setCallEventType( CallEventType.TELEPHONE_INTERCONNECT );
@@ -1401,6 +1419,8 @@ public class P25DecoderState extends DecoderState
broadcast( mCurrentCallEvent );
}
updateTo( tivcu.getAddress() );
}
else
{
@@ -1466,10 +1486,6 @@ public class P25DecoderState extends DecoderState
UnitToUnitVoiceChannelUser uuvcu =
(UnitToUnitVoiceChannelUser)ldu;
updateFrom( uuvcu.getSourceAddress() );
updateTo( uuvcu.getTargetAddress() );
if( mCurrentCallEvent.getCallEventType() != CallEventType.UNIT_TO_UNIT_CALL )
{
mCurrentCallEvent.setCallEventType( CallEventType.UNIT_TO_UNIT_CALL );
@@ -1484,6 +1500,9 @@ public class P25DecoderState extends DecoderState
broadcast( mCurrentCallEvent );
}
updateFrom( uuvcu.getSourceAddress() );
updateTo( uuvcu.getTargetAddress() );
}
else
{
@@ -1502,7 +1521,7 @@ public class P25DecoderState extends DecoderState
private void processTSBK( TSBKMessage tsbk )
{
/* Trunking Signalling Block Messages - indicates Control Channel */
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.CONTROL ) );
broadcast( new DecoderStateEvent( this, Event.START, State.CONTROL ) );
if( tsbk.getVendor() == Vendor.STANDARD )
{
@@ -1631,11 +1650,7 @@ public class P25DecoderState extends DecoderState
*/
private void processPDU( PDUMessage pdu )
{
if( pdu instanceof PacketData || pdu instanceof PDUTypeUnknown )
{
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.DATA ) );
}
else if( pdu instanceof PDUConfirmedMessage )
if( pdu instanceof PDUConfirmedMessage )
{
broadcast( new DecoderStateEvent( this, Event.CONTINUATION, State.DATA ) );
@@ -1643,7 +1658,7 @@ public class P25DecoderState extends DecoderState
switch( pduc.getPDUType() )
{
case SNDCP_ACTIVATE_TDS_CONTEXT_ACCEPT:
case SN_ACTIVATE_TDS_CONTEXT_ACCEPT:
SNDCPActivateTDSContextAccept satca =
(SNDCPActivateTDSContextAccept)pduc;
@@ -1655,7 +1670,7 @@ public class P25DecoderState extends DecoderState
.to( satca.getLogicalLinkID() )
.build() );
break;
case SNDCP_ACTIVATE_TDS_CONTEXT_REJECT:
case SN_ACTIVATE_TDS_CONTEXT_REJECT:
SNDCPActivateTDSContextReject satcr =
(SNDCPActivateTDSContextReject)pduc;
@@ -1680,7 +1695,7 @@ public class P25DecoderState extends DecoderState
.from( satcreq.getLogicalLinkID() )
.build() );
break;
case SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT:
case SN_DEACTIVATE_TDS_CONTEXT_ACCEPT:
SNDCPDeactivateTDSContext sdtca =
(SNDCPDeactivateTDSContext)pduc;
@@ -1692,7 +1707,7 @@ public class P25DecoderState extends DecoderState
.from( sdtca.getLogicalLinkID() )
.build() );
break;
case SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST:
case SN_DEACTIVATE_TDS_CONTEXT_REQUEST:
SNDCPDeactivateTDSContext sdtcreq =
(SNDCPDeactivateTDSContext)pduc;
@@ -1704,7 +1719,7 @@ public class P25DecoderState extends DecoderState
.from( sdtcreq.getLogicalLinkID() )
.build() );
break;
case SNDCP_RF_CONFIRMED_DATA:
case SN_RF_CONFIRMED_DATA:
SNDCPUserData sud = (SNDCPUserData)pduc;
StringBuilder sbFrom = new StringBuilder();
@@ -1733,10 +1748,8 @@ public class P25DecoderState extends DecoderState
.to( pduc.getLogicalLinkID() )
.build() );
break;
case SNDCP_RF_UNCONFIRMED_DATA:
break;
default:
// mLog.debug( "PDUC - Unrecognized Message: " + pduc.toString() );
mLog.debug( "PDUC - Unrecognized Message: " + pduc.toString() );
break;
}
}
@@ -3087,9 +3100,16 @@ public class P25DecoderState extends DecoderState
if( mToTalkgroup == null || !mToTalkgroup.contentEquals( to ) )
{
mToTalkgroup = to;
broadcast( ChangedAttribute.TO_TALKGROUP );
if( mCurrentCallEvent != null &&
( mCurrentCallEvent.getToID() == null ||
!mCurrentCallEvent.getToID().contentEquals( to ) ) )
{
mCurrentCallEvent.setToID( to );
broadcast( mCurrentCallEvent );
}
if( hasAliasList() )
{
mToAlias = getAliasList().getTalkgroupAlias( mToTalkgroup );
@@ -3098,20 +3118,12 @@ public class P25DecoderState extends DecoderState
{
mToAlias = null;
}
broadcast( ChangedAttribute.TO_TALKGROUP_ALIAS );
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.TO, mToTalkgroup, mToAlias, true ) );
if( mCurrentCallEvent != null &&
( mCurrentCallEvent.getToID() == null ||
!mCurrentCallEvent.getToID().contentEquals( to ) ) )
{
mCurrentCallEvent.setToID( to );
broadcast( mCurrentCallEvent );
}
}
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.TO, mToTalkgroup, mToAlias, true ) );
}
}
@@ -3127,6 +3139,14 @@ public class P25DecoderState extends DecoderState
mFromTalkgroup = from;
broadcast( ChangedAttribute.FROM_TALKGROUP );
if( mCurrentCallEvent != null &&
mCurrentCallEvent.getFromID() == null ||
!mCurrentCallEvent.getFromID().contentEquals( from ) )
{
mCurrentCallEvent.setFromID( from );
broadcast( mCurrentCallEvent );
}
if( hasAliasList() )
{
mFromAlias = getAliasList().getTalkgroupAlias( mFromTalkgroup );
@@ -3137,19 +3157,10 @@ public class P25DecoderState extends DecoderState
}
broadcast( ChangedAttribute.FROM_TALKGROUP_ALIAS );
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.FROM, mFromTalkgroup, mFromAlias, true ) );
if( mCurrentCallEvent != null &&
mCurrentCallEvent.getFromID() == null ||
!mCurrentCallEvent.getFromID().contentEquals( from ) )
{
mCurrentCallEvent.setFromID( from );
broadcast( mCurrentCallEvent );
}
}
/* Send audio metadata update */
broadcast( new Metadata( MetadataType.FROM, mFromTalkgroup, mFromAlias, true ) );
}
}

View File

@@ -87,8 +87,6 @@ public class P25Message extends Message
sb.append( " " );
sb.append( getDUID().getLabel() );
sb.append( " DATA UNIT ID:" + mMessage.getInt( DUID ) );
return sb.toString();
}

View File

@@ -1,6 +1,5 @@
package module.decode.p25.message.pdu;
import module.decode.p25.message.pdu.confirmed.PacketData;
import module.decode.p25.message.pdu.osp.control.AdjacentStatusBroadcastExtended;
import module.decode.p25.message.pdu.osp.control.CallAlertExtended;
import module.decode.p25.message.pdu.osp.control.GroupAffiliationQueryExtended;
@@ -122,8 +121,7 @@ public class PDUMessageFactory
}
return new PDUMessage( message, duid, aliasList );
case PACKET_DATA:
return new PacketData( message, aliasList );
case UNCONFIRMED_MULTI_BLOCK_TRUNKING_CONTROL:
return new PDUMessage( message, duid, aliasList );
default:

View File

@@ -48,27 +48,19 @@ public class PDUConfirmedMessageFactory
case UNENCRYPTED_USER_DATA:
switch( message.getPDUType() )
{
case SNDCP_ACTIVATE_TDS_CONTEXT_ACCEPT:
case SN_ACTIVATE_TDS_CONTEXT_ACCEPT:
return new SNDCPActivateTDSContextAccept( message );
case SNDCP_ACTIVATE_TDS_CONTEXT_REJECT:
case SN_ACTIVATE_TDS_CONTEXT_REJECT:
return new SNDCPActivateTDSContextReject( message );
case SN_ACTIVATE_TDS_CONTEXT_REQUEST:
return new SNDCPActivateTDSContextRequest( message );
case SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT:
case SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST:
case SN_DEACTIVATE_TDS_CONTEXT_ACCEPT:
case SN_DEACTIVATE_TDS_CONTEXT_REQUEST:
return new SNDCPDeactivateTDSContext( message );
case SNDCP_RF_CONFIRMED_DATA:
case SN_RF_CONFIRMED_DATA:
return new SNDCPUserData( message );
case SNDCP_RF_UNCONFIRMED_DATA:
case SN_RF_UNCONFIRMED_DATA:
break;
case PDU_TYPE_6:
case PDU_TYPE_7:
case PDU_TYPE_8:
case PDU_TYPE_9:
case PDU_TYPE_10:
case PDU_TYPE_11:
return new PDUTypeUnknown( message );
case UNKNOWN:
default:
break;
}

View File

@@ -1,55 +0,0 @@
package module.decode.p25.message.pdu.confirmed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PDUTypeUnknown extends PDUConfirmedMessage
{
public final static Logger mLog =
LoggerFactory.getLogger( PDUTypeUnknown.class );
public PDUTypeUnknown( PDUConfirmedMessage message )
{
super( message );
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( "NAC:" );
sb.append( getNAC() );
sb.append( " LLID:" );
sb.append( getLogicalLinkID() );
sb.append( " PACKET DATA UNIT CONFIRMED - " );
sb.append( getPDUType().getLabel() );
sb.append( " CRC[" );
sb.append( getErrorStatus() );
sb.append( "]" );
sb.append( " PACKET #" );
sb.append( getPacketSequenceNumber() );
if( isFinalFragment() && getFragmentSequenceNumber() == 0 )
{
sb.append( ".C" );
}
else
{
sb.append( "." );
sb.append( getFragmentSequenceNumber() );
if( isFinalFragment() )
{
sb.append( "C" );
}
}
sb.append( " " );
sb.append( mMessage.toString() );
return sb.toString();
}
}

View File

@@ -1,66 +0,0 @@
package module.decode.p25.message.pdu.confirmed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import alias.AliasList;
import bits.BinaryMessage;
public class PacketData extends PDUConfirmedMessage
{
public final static Logger mLog =
LoggerFactory.getLogger( PacketData.class );
public static final int DATA_BLOCK_START = 176;
public PacketData( BinaryMessage message, AliasList aliasList )
{
super( message, aliasList );
}
@Override
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( "NAC:" );
sb.append( getNAC() );
sb.append( " PDUC LLID:" );
sb.append( getLogicalLinkID() );
sb.append( " PACKET DATA" );
sb.append( " CRC[" );
sb.append( getErrorStatus() );
sb.append( "]" );
if( !mMessage.get( FINAL_FRAGMENT_FLAG ) )
{
sb.append( " RESENDING" );
}
sb.append( " PACKET #" );
sb.append( getPacketSequenceNumber() );
if( isFinalFragment() && getFragmentSequenceNumber() == 0 )
{
sb.append( ".C" );
}
else
{
sb.append( "." );
sb.append( getFragmentSequenceNumber() );
if( isFinalFragment() )
{
sb.append( "C" );
}
}
sb.append( " " );
sb.append( mMessage.toString() );
return sb.toString();
}
}

View File

@@ -49,7 +49,7 @@ public class SNDCPDeactivateTDSContext extends PDUConfirmedMessage
public String getDeactivationType()
{
if( getPDUType() == PDUType.SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST )
if( getPDUType() == PDUType.SN_DEACTIVATE_TDS_CONTEXT_REQUEST )
{
return mMessage.getInt( DEACTIVATION_TYPE ) == 0 ?
"ALL NSAPIS" : "THIS NSAPI";

View File

@@ -1,7 +1,5 @@
package module.decode.p25.message.tsbk;
import alias.AliasList;
import bits.BinaryMessage;
import module.decode.p25.message.tsbk.motorola.ControlChannelBaseStationIdentification;
import module.decode.p25.message.tsbk.motorola.MotorolaOpcode;
import module.decode.p25.message.tsbk.motorola.MotorolaTSBKMessage;
@@ -21,7 +19,6 @@ import module.decode.p25.message.tsbk.osp.control.ExtendedFunctionCommand;
import module.decode.p25.message.tsbk.osp.control.GroupAffiliationQuery;
import module.decode.p25.message.tsbk.osp.control.GroupAffiliationResponse;
import module.decode.p25.message.tsbk.osp.control.IdentifierUpdateNonVUHF;
import module.decode.p25.message.tsbk.osp.control.IdentifierUpdateTDMA;
import module.decode.p25.message.tsbk.osp.control.IdentifierUpdateVUHF;
import module.decode.p25.message.tsbk.osp.control.LocationRegistrationResponse;
import module.decode.p25.message.tsbk.osp.control.MessageUpdate;
@@ -59,6 +56,8 @@ import module.decode.p25.message.tsbk.osp.voice.UnitToUnitVoiceChannelGrantUpdat
import module.decode.p25.reference.DataUnitID;
import module.decode.p25.reference.Opcode;
import module.decode.p25.reference.Vendor;
import alias.AliasList;
import bits.BinaryMessage;
public class TSBKMessageFactory
{
@@ -120,8 +119,6 @@ public class TSBKMessageFactory
case IDENTIFIER_UPDATE_NON_VUHF:
return new IdentifierUpdateNonVUHF( message, duid,
aliasList );
case IDENTIFIER_UPDATE_TDMA:
return new IdentifierUpdateTDMA( message, duid, aliasList );
case IDENTIFIER_UPDATE_VHF_UHF_BANDS:
return new IdentifierUpdateVUHF( message, duid,
aliasList );

View File

@@ -1,159 +0,0 @@
package module.decode.p25.message.tsbk.osp.control;
import module.decode.p25.reference.DataUnitID;
import module.decode.p25.reference.Opcode;
import alias.AliasList;
import bits.BinaryMessage;
public class IdentifierUpdateTDMA extends IdentifierUpdate
{
public static final int[] CHANNEL_TYPE = { 84,85,86,87 };
public static final int TRANSMIT_OFFSET_SIGN = 88;
public static final int[] TRANSMIT_OFFSET = { 89,90,91,92,93,94,95,96,97,98,
99,100,101 };
public IdentifierUpdateTDMA( BinaryMessage message,
DataUnitID duid,
AliasList aliasList )
{
super( message, duid, aliasList );
}
@Override
public String getEventType()
{
return Opcode.IDENTIFIER_UPDATE_TDMA.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( getMessageStub() );
sb.append( " IDEN:" + getIdentifier() );
sb.append( " BASE:" + getBaseFrequency() );
sb.append( " BW:" + getBandwidth() );
sb.append( " SPACING:" + getChannelSpacing() );
sb.append( " OFFSET:" + getTransmitOffset() );
sb.append( " TYPE:" + getChannelType().toString() );
return sb.toString();
}
public ChannelType getChannelType()
{
return ChannelType.fromValue( mMessage.getInt( CHANNEL_TYPE) );
}
/**
* Channel bandwidth in hertz
*/
public int getBandwidth()
{
return getChannelType().getBandwidth();
}
/**
* Transmit offset in hertz
*/
@Override
public long getTransmitOffset()
{
long offset = mMessage.getLong( TRANSMIT_OFFSET ) *
getChannelSpacing();
if( mMessage.get( TRANSMIT_OFFSET_SIGN ) )
{
return offset;
}
else
{
return -offset;
}
}
public enum ChannelType
{
TYPE_0( AccessType.FDMA, 12500, 1, Vocoder.HALF_RATE ),
TYPE_1( AccessType.FDMA, 12500, 1, Vocoder.FULL_RATE ),
TYPE_2( AccessType.FDMA, 6250, 1, Vocoder.HALF_RATE ),
TYPE_3( AccessType.TDMA, 12500, 2, Vocoder.HALF_RATE ),
TYPE_4( AccessType.TDMA, 25000, 4, Vocoder.HALF_RATE ),
TYPE_5( AccessType.TDMA, 12500, 2, Vocoder.HALF_RATE ), //HD8PSK simulcast
UNKNOWN( AccessType.UNKNOWN, 0, 0, Vocoder.HALF_RATE );
private AccessType mAccessType;
private int mBandwidth;
private int mSlotsPerCarrier;
private Vocoder mVocoder;
private ChannelType( AccessType accessType,
int bandwidth,
int slots,
Vocoder vocoder )
{
mAccessType = accessType;
mBandwidth = bandwidth;
mSlotsPerCarrier = slots;
mVocoder = vocoder;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
if( this.equals( TYPE_5 ) )
{
sb.append("H-D8PSK SIMULCAST " );
}
sb.append( mAccessType.name() );
sb.append( " BW:" + mBandwidth );
sb.append( " SLOT/CARRIER:" + mSlotsPerCarrier );
sb.append( " VOCODER:" + mVocoder.name() );
return sb.toString();
}
public static ChannelType fromValue( int value )
{
if( 0 <= value && value <= 5 )
{
return ChannelType.values()[ value ];
}
return ChannelType.UNKNOWN;
}
public AccessType getAccessType()
{
return mAccessType;
}
public int getBandwidth()
{
return mBandwidth;
}
public int getSlotsPerCarrier()
{
return mSlotsPerCarrier;
}
public Vocoder getVocoder()
{
return mVocoder;
}
}
public enum AccessType
{
FDMA,TDMA,UNKNOWN;
}
public enum Vocoder
{
HALF_RATE, FULL_RATE;
}
}

View File

@@ -1,10 +1,8 @@
package module.decode.p25.message.tsbk.osp.control;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import module.decode.p25.message.tsbk.TSBKMessage;
@@ -14,21 +12,20 @@ import alias.AliasList;
import bits.BinaryMessage;
/**
* Sync Broadcast - used to broadcast FDMA-TDMA timing synchronization
* information so that a subscriber unit that is time synchronized on an FDMA
* control channel is also time synchronized with all TDMA traffic channels at
* the site.
* Sync Broadcast - used to broadcast FDMA-TDMA synchronization timestamp so
* that a subscriber unit that is time synchronized on an FDMA control channel
* is also synchronized with a TDMA traffic channel.
*/
public class SyncBroadcast extends TSBKMessage
{
public static final int[] RESERVED = { 80,81,82,83,84,85,86,87,88,89,90,91,92 };
public static final int SYSTEM_TIME_NOT_LOCKED_TO_EXTERNAL_REFERENCE = 93;
public static final int MICRO_SLOTS_TO_MINUTE_ROLLOVER_UNLOCKED = 94;
public static final int[] LEAP_SECOND_CORRECTION = { 95,96 };
public static final int LOCAL_TIME_OFFSET_VALID = 97;
public static final int US = 92;
public static final int IST = 93;
public static final int MMU = 94;
public static final int[] MC = { 95,96 };
public static final int VL = 97;
public static final int LOCAL_TIME_OFFSET_SIGN = 98;
public static final int[] LOCAL_TIME_OFFSET_HOURS = { 99,100,101,102 };
public static final int LOCAL_TIME_OFFSET_HALF_HOUR = 103;
public static final int[] LOCAL_TIME_OFFSET = { 99,100,101,102 };
public static final int LOCAL_TIME_OFFSET_HALF = 103;
public static final int[] YEAR = { 104,105,106,107,108,109,110 };
public static final int[] MONTH = { 111,112,113,114 };
@@ -39,10 +36,7 @@ public class SyncBroadcast extends TSBKMessage
139,140,141,142,143 };
public static final int[] TSBK_CRC = { 144,145,146,147,148,149,150,151,152,
153,154,155,156,157,158,159 };
private static final DateFormat TIME_FORMATTER = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS Z" );
private static final TimeZone NO_TIME_ZONE = new SimpleTimeZone( 0, "NONE" );
public SyncBroadcast( BinaryMessage message,
DataUnitID duid,
AliasList aliasList )
@@ -62,41 +56,24 @@ public class SyncBroadcast extends TSBKMessage
sb.append( getMessageStub() );
sb.append( " SYSTEM TIME" );
if( isSystemTimeNotLockedToExternalReference() )
{
sb.append( " UNLOCKED" );
}
sb.append( ":" );
TIME_FORMATTER.setTimeZone( getTimeZone() );
sb.append( " " + TIME_FORMATTER.format( new Date( getSystemTime() ) ) );
sb.append( " LEAP-SECOND CORRECTION:" + getLeapSecondCorrection() + "mS" );
if( isMicroslotsLockedToMinuteRollover() )
{
sb.append( " MICROSLOT-MINUTE ROLLOVER:LOCKED" );
}
else
{
sb.append( " MICROSLOT-MINUTE ROLLOVER:UNLOCKED" );
}
sb.append( " " + new Date( getTime() ).toString() );
sb.append( " TIME ZONE OFFSET:" + getTimeZone().toUpperCase() );
sb.append( " US:" + isUS() );
sb.append( " IST:" + isIST() );
sb.append( " MMU:" + isMMU() );
sb.append( " VL:" + isVL() );
return sb.toString();
}
/**
* System Time (UTC) in milliseconds since java epoch
* Returns the time sync in java time (ie milliseconds since epoch )
*/
public long getSystemTime()
public long getTime()
{
Calendar cal = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) );
Calendar cal = new GregorianCalendar();
cal.clear();
cal.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
cal.set( Calendar.YEAR, getYear() );
cal.set( Calendar.MONTH, getMonth() - 1 );
cal.set( Calendar.DAY_OF_MONTH, getDay() );
@@ -107,165 +84,102 @@ public class SyncBroadcast extends TSBKMessage
return cal.getTimeInMillis();
}
/**
* System Time not locked to external time reference indicator
*/
public boolean isSystemTimeNotLockedToExternalReference()
public boolean isUS()
{
return mMessage.get( SYSTEM_TIME_NOT_LOCKED_TO_EXTERNAL_REFERENCE );
return mMessage.get( US );
}
/**
* Micro-slot-to-Minute rollover boundary lock indicator.
*
* Note: we invert the message value so that true indicates that the micro
* slots and minute rollovers are locked, whereas the ICD uses false to
* indicate a lock.
*
* @return true if the microslots rollover at each minute interval is locked
* to the system time minute rollover.
*
* @return false if the microslots and minutes rollover are not locked. This
* indicates that the microslots minute rollover is free rolling.
*
* Daylight Savings Time
*/
public boolean isMicroslotsLockedToMinuteRollover()
public boolean isIST()
{
return !mMessage.get( MICRO_SLOTS_TO_MINUTE_ROLLOVER_UNLOCKED );
return mMessage.get( IST );
}
/**
* Leap second correction value that should be applied to the system time.
*
* The leap-second correction field indicates the number of 2.5 millisecond
* units that must be added to the system time to account for the insertion
* of leap seconds when the system time is represented as UTC universal time.
*
* @return leap-second correction value in milliseconds 0.0-10.0
* No idea ...
*/
public double getLeapSecondCorrection()
public boolean isMMU()
{
return (double)mMessage.getInt( LEAP_SECOND_CORRECTION ) * 2.5d;
}
/**
* Indicates the local time offset fields contain valid information.
*/
public boolean isValidLocalTimeOffset()
{
return !mMessage.get( LOCAL_TIME_OFFSET_VALID );
return mMessage.get( MMU );
}
/**
* Local time zone offset from UTC universal time (zulu) when the VALID
* LOCAL TIME OFFSET flag indicates a valid offset. Otherwise, this method
* returns a static +00:00 indicating no local time offset.
* Millenium ...?
*/
public TimeZone getTimeZone()
public int getMC()
{
if( isValidLocalTimeOffset() )
{
int offset = 0;
offset += mMessage.getInt( LOCAL_TIME_OFFSET_HOURS ) * 3600000;
offset += mMessage.get( LOCAL_TIME_OFFSET_HALF_HOUR ) ? 1800000 : 0;
offset = mMessage.get( LOCAL_TIME_OFFSET_SIGN ) ? -offset : offset;
return new SimpleTimeZone( offset, "LOCAL" );
}
else
{
return NO_TIME_ZONE;
}
return mMessage.getInt( MC );
}
/**
* System time - year.
*
* @return year in range 2000-2127
* No idea ....
*/
public boolean isVL()
{
return mMessage.get( VL );
}
/**
* Calculates the time zone from the local time offset field.
*/
public String getTimeZone()
{
StringBuilder sb = new StringBuilder();
sb.append( mMessage.get( LOCAL_TIME_OFFSET_SIGN ) ? "-" : "+" );
int hours = mMessage.getInt( LOCAL_TIME_OFFSET );
sb.append( ( hours < 10 ? "0" : "" ) + String.valueOf( hours ) );
sb.append( ":" );
sb.append( mMessage.get( LOCAL_TIME_OFFSET_HALF ) ? "30" : "00" );
if( mMessage.get( IST ) )
{
sb.append( " DST" );
}
return sb.toString();
}
public int getYear()
{
return 2000 + mMessage.getInt( YEAR );
}
/**
* System time - month
*
* @return month 1-12 where 1=January and 12=December
*/
public int getMonth()
{
return mMessage.getInt( MONTH );
}
/**
* System time - day of month
*
* @return day of month in range 1-31
*/
public int getDay()
{
return mMessage.getInt( DAY );
}
/**
* System time - hours
*
* @return hours in range 0 - 23
*/
public int getHours()
{
return mMessage.getInt( HOURS );
}
/**
* System time - minutes
*
* @return minutes in range 0 - 59
*/
public int getMinutes()
{
return mMessage.getInt( MINUTES );
}
/**
* System time - milli-seconds
*
* Note: sub-millisecond values are rounded to nearest millisecond unit to
* conform to java Date internal milli-second precision level.
*
* @return milli-seconds in range 0 - 59999;
*/
public int getMilliSeconds()
{
return (int)( (double)getMicroSlots() * 7.5 );
}
/**
* TDMA Micro Slots.
*
* Number of 7.5 millisecond micro slots since the last minute rollover, or
* since the last micro-slot counter rollover when the the micro-slot to
* minute rollover is unlocked.
*
* @see isMicroslotsLockedToMinuteRollover() method.
*
* This value supports mobile subscriber timing alignment with a TDMA traffic
* channel when a channel is granted from the control channels, so that when
* the mobile changes from the control channel to the traffic channel, it is
* already aligned with the traffic channel TDMA timing.
*
* Super frames occur every 360 ms (48 micro-slots) on FDMA and Ultra frames
* occur every 4 super frames on TDMA.
*
* Valid micro-slot values range 0-7999 and represent 60,000
* milliseconds ( 8000 x 7.5 ms).
*
* @return number of 7.5 mS micro-slots since last minute or micro-slot
* rollover
* Micro Slots - each uslot = 7.5 milliseconds. The value ranges 0 - 7999
* and represents 60,000 milliseconds ( 8000 x 7.5 ms). Superframes occur
* every 360 ms (48 micro-slots) on FDMA and Ultraframes occur every 4
* super frames on TDMA.
*/
public int getMicroSlots()
{

View File

@@ -53,7 +53,7 @@ public enum Opcode
TDMA_SYNC_BROADCAST( "TDMA_SYNC_BCST ", "FDMA-TDMA Sync Broadcast", 48 ),
RESERVED_31( "RESERVED_31 ", "Reserved", 49 ),
RESERVED_32( "RESERVED_32 ", "Reserved", 50 ),
IDENTIFIER_UPDATE_TDMA( "IDEN_UPDATE_TDMA", "Identifier Update for TDMA", 51 ),
RESERVED_33( "RESERVED_33 ", "Reserved", 51 ),
IDENTIFIER_UPDATE_VHF_UHF_BANDS( "IDEN_UPDATE_VUHF", "Identifier Update for VHF/UHF Bands", 52 ),
TIME_DATE_ANNOUNCEMENT( "TIME_DATE_ANNOUN", "Time and Date Announcement", 53 ),
ROAMING_ADDRESS_COMMAND( "ROAM_ADDR_CMD ", "Roaming Address Command", 54 ),

View File

@@ -3,18 +3,12 @@ package module.decode.p25.reference;
public enum PDUType
{
/* Outbound */
SNDCP_ACTIVATE_TDS_CONTEXT_ACCEPT( "SNDCP-ACTIVATE TDS CONTEXT ACCEPT", 0 ),
SNDCP_DEACTIVATE_TDS_CONTEXT_ACCEPT( "SNDCP-DEACTIVATE TDS CONTEXT ACCEPT", 1 ),
SNDCP_DEACTIVATE_TDS_CONTEXT_REQUEST( "SNDCP-DEACTIVATE TDS CONTEXT REQUEST", 2 ),
SNDCP_ACTIVATE_TDS_CONTEXT_REJECT( "SNDCP-ACTIVATE TDS CONTEXT REJECT", 3 ),
SNDCP_RF_UNCONFIRMED_DATA( "SNDCP-RF UNCONFIRMED DATA", 4 ),
SNDCP_RF_CONFIRMED_DATA( "SNDCP-RF CONFIRMED DATA", 5 ),
PDU_TYPE_6( "PDU TYPE 6 UNKNOWN", 6 ),
PDU_TYPE_7( "PDU TYPE 7 UNKNOWN", 7 ),
PDU_TYPE_8( "PDU TYPE 8 UNKNOWN", 8 ),
PDU_TYPE_9( "PDU TYPE 9 UNKNOWN", 9 ),
PDU_TYPE_10( "PDU TYPE 10 UNKNOWN", 10 ),
PDU_TYPE_11( "PDU TYPE 11 UNKNOWN", 11 ),
SN_ACTIVATE_TDS_CONTEXT_ACCEPT( "SN-ACTIVATE TDS CONTEXT ACCEPT", 0 ),
SN_DEACTIVATE_TDS_CONTEXT_ACCEPT( "SN-DEACTIVATE TDS CONTEXT ACCEPT", 1 ),
SN_DEACTIVATE_TDS_CONTEXT_REQUEST( "SN-DEACTIVATE TDS CONTEXT REQUEST", 2 ),
SN_ACTIVATE_TDS_CONTEXT_REJECT( "SN-ACTIVATE TDS CONTEXT REJECT", 3 ),
SN_RF_UNCONFIRMED_DATA( "SN-RF UNCONFIRMED DATA", 4 ),
SN_RF_CONFIRMED_DATA( "SN-RF CONFIRMED DATA", 5 ),
/* Inbound */
SN_ACTIVATE_TDS_CONTEXT_REQUEST( "SN-ACTIVATE TDS CONTEXT REQUEST", 0 ),
@@ -42,7 +36,7 @@ public enum PDUType
public static PDUType fromValue( int value, boolean outbound )
{
if( outbound && 0 <= value && value <= 11 )
if( outbound && 0 <= value && value <= 5 )
{
return values()[ value ];
}

View File

@@ -2,7 +2,7 @@ package module.decode.p25.reference;
public enum ServiceAccessPoint
{
UNENCRYPTED_USER_DATA( "UNENCRYPTED USER DATA", 0 ),
UNENCRYPTED_USER_DATA( "USER DATA", 0 ),
ENCRYPTED_USER_DATA( "ENCRYPTED USER DATA", 1 ),
CIRCUIT_DATA( "CIRCUIT DATA", 2 ),
CIRCUIT_DATA_CONTROL( "CIRCUIT DATA CONTROL", 3 ),