Added CRC checks to 2,3 and 4 block PDU messages. Enforcing message validation via the message processor. Updated the P25 Activity Summary to show frequencies in megahertz and to add site aliasing to the summary text.

This commit is contained in:
dennis.sheirer
2014-12-17 02:10:43 +00:00
parent e7b446b3b5
commit 63eaef664b
25 changed files with 467 additions and 75 deletions

View File

@@ -17,15 +17,20 @@
******************************************************************************/
package decode.p25;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import alias.Alias;
import alias.AliasList;
import controller.activity.ActivitySummaryProvider;
import decode.p25.message.P25Message;
import decode.p25.message.pdu.PDUMessage;
import decode.p25.message.pdu.osp.control.NetworkStatusBroadcastExtended;
import decode.p25.message.pdu.osp.control.RFSSStatusBroadcastExtended;
@@ -42,6 +47,12 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
{
private static final int sINT_NULL_VALUE = -1;
private final static Logger mLog =
LoggerFactory.getLogger( P25ActivitySummary.class );
private static final DecimalFormat mFrequencyFormatter =
new DecimalFormat( "0.000000" );
private AliasList mAliasList;
private NetworkStatusBroadcast mNetworkStatus;
@@ -69,6 +80,11 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
@Override
public void receive( Message message )
{
if( !message.isValid() )
{
mLog.debug( "Got an invalid message!" );
}
if( message instanceof TSBKMessage )
{
if( message instanceof AdjacentStatusBroadcast )
@@ -118,7 +134,7 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
sb.append( "Activity Summary\n" );
sb.append( "Decoder:\tP25\n" );
sb.append( "---------- THIS SITE --------------" );
sb.append( "===================== THIS SITE ======================" );
if( mNetworkStatus != null )
{
@@ -126,14 +142,6 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
sb.append( "\nSYSTEM:\t" + mNetworkStatus.getSystemID() );
sb.append( "\nWACN:\t" + mNetworkStatus.getWACN() );
sb.append( "\nLRA:\t" + mNetworkStatus.getLocationRegistrationArea() );
sb.append( "\nSERVICES:\t" + SystemService.toString(
mNetworkStatus.getSystemServiceClass() ) );
sb.append( "\nPCCH:\tDNLINK " + mNetworkStatus.getDownlinkFrequency() +
" [" + mNetworkStatus.getIdentifier() + "-" +
mNetworkStatus.getChannel() + "]\n" );
sb.append( "\tUPLINK " + mNetworkStatus.getUplinkFrequency() + " [" +
mNetworkStatus.getIdentifier() + "-" +
mNetworkStatus.getChannel() + "]\n" );
}
else if( mNetworkStatusExtended != null )
{
@@ -141,16 +149,59 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
sb.append( "\nSYSTEM:\t" + mNetworkStatusExtended.getSystemID() );
sb.append( "\nWACN:\t" + mNetworkStatusExtended.getWACN() );
sb.append( "\nLRA:\t" + mNetworkStatusExtended.getLocationRegistrationArea() );
sb.append( "\nSERVICES:\t" + SystemService.toString(
mNetworkStatusExtended.getSystemServiceClass() ) );
sb.append( "\nPCCH:\tDNLINK " + mNetworkStatusExtended.getDownlinkFrequency() +
" [" + mNetworkStatusExtended.getTransmitIdentifier() + "-" +
mNetworkStatusExtended.getTransmitChannel() + "]\n" );
sb.append( "\tUPLINK " + mNetworkStatusExtended.getUplinkFrequency() + " [" +
mNetworkStatusExtended.getReceiveIdentifier() + "-" +
mNetworkStatusExtended.getReceiveChannel() + "]" );
}
String site = null;
if( mRFSSStatusMessage != null )
{
site = mRFSSStatusMessage.getRFSubsystemID() + "-" + mRFSSStatusMessage.getSiteID();
}
else if( mRFSSStatusMessageExtended != null )
{
site = mRFSSStatusMessageExtended.getRFSubsystemID() + "-" +
mRFSSStatusMessageExtended.getSiteID();
}
sb.append( "\nRFSS-SITE:\t" + site );
if( mAliasList != null )
{
Alias siteAlias = mAliasList.getSiteID( site );
if( siteAlias != null )
{
sb.append( " " + siteAlias.getName() );
}
}
if( mNetworkStatus != null )
{
sb.append( "\nSERVICES:\t" + SystemService.toString(
mNetworkStatus.getSystemServiceClass() ) );
sb.append( "\nPCCH:\tDNLINK " + mFrequencyFormatter.format(
(double)mNetworkStatus.getDownlinkFrequency() / 1E6d ) +
" [" + mNetworkStatus.getIdentifier() + "-" +
mNetworkStatus.getChannel() + "]\n" );
sb.append( "\tUPLINK " + mFrequencyFormatter.format(
(double)mNetworkStatus.getUplinkFrequency() / 1E6d ) + " [" +
mNetworkStatus.getIdentifier() + "-" +
mNetworkStatus.getChannel() + "]\n" );
}
else if( mNetworkStatusExtended != null )
{
sb.append( "\nSERVICES:\t" + SystemService.toString(
mNetworkStatusExtended.getSystemServiceClass() ) );
sb.append( "\nPCCH:\tDNLINK " + mFrequencyFormatter.format(
(double)mNetworkStatusExtended.getDownlinkFrequency() / 1E6d ) +
" [" + mNetworkStatusExtended.getTransmitIdentifier() + "-" +
mNetworkStatusExtended.getTransmitChannel() + "]\n" );
sb.append( "\tUPLINK " + mFrequencyFormatter.format(
(double)mNetworkStatusExtended.getUplinkFrequency() / 1E6d ) +
" [" + mNetworkStatusExtended.getReceiveIdentifier() + "-" +
mNetworkStatusExtended.getReceiveChannel() + "]" );
}
if( mSecondaryControlChannels.isEmpty() )
{
sb.append( "\nSCCH:\tNONE" );
@@ -159,45 +210,33 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
{
for( SecondaryControlChannelBroadcast sec: mSecondaryControlChannels )
{
sb.append( "\nSCCH:\tDNLINK " + sec.getDownlinkFrequency1() +
sb.append( "\nSCCH:\tDNLINK " + mFrequencyFormatter.format(
(double)sec.getDownlinkFrequency1() / 1E6d ) +
" [" + sec.getIdentifier1() + "-" + sec.getChannel1() + "]\n" );
sb.append( "\tUPLINK " + sec.getUplinkFrequency1() + " [" +
sb.append( "\tUPLINK " + mFrequencyFormatter.format(
(double)sec.getUplinkFrequency1() / 1E6d ) + " [" +
sec.getIdentifier1() + "-" + sec.getChannel1() + "]\n" );
if( sec.hasChannel2() )
{
sb.append( "\nSCCH:\tDNLINK " + sec.getDownlinkFrequency2() +
sb.append( "\nSCCH:\tDNLINK " + mFrequencyFormatter.format(
(double)sec.getDownlinkFrequency2() / 1E6d ) +
" [" + sec.getIdentifier2() + "-" + sec.getChannel2() + "]\n" );
sb.append( "\tUPLINK " + sec.getUplinkFrequency2() + " [" +
sb.append( "\tUPLINK " + mFrequencyFormatter.format(
(double)sec.getUplinkFrequency2() / 1E6d ) + " [" +
sec.getIdentifier2() + "-" + sec.getChannel2() + "]" );
}
}
}
if( mRFSSStatusMessage != null )
{
sb.append( "\nRFSS:\t" + mRFSSStatusMessage.getRFSubsystemID() );
sb.append( "\nSITE:\t" + mRFSSStatusMessage.getSiteID() );
if( mAliasList != null )
{
/* Add site alias here */
}
}
else if( mRFSSStatusMessageExtended != null )
{
sb.append( "\nRFSS:\t" + mRFSSStatusMessageExtended.getRFSubsystemID() );
sb.append( "\nSITE:\t" + mRFSSStatusMessageExtended.getSiteID() );
}
sb.append( "\n\n----------- NEIGHBORS -------------" );
sb.append( "\n\n=================== NEIGHBORS ======================" );
if( mNeighborMap.isEmpty() )
{
sb.append( "\n\tNONE\n" );
sb.append( "------------------------\n" );
sb.append( "\n----------------------------------------------------" );
}
else
{
@@ -206,11 +245,25 @@ public class P25ActivitySummary implements ActivitySummaryProvider,
sb.append( "\nNAC:\t" + neighbor.getNAC() );
sb.append( "\nSYSTEM:\t" + neighbor.getSystemID() );
sb.append( "\nLRA:\t" + neighbor.getLocationRegistrationArea() );
sb.append( "\nRFSS:\t" + neighbor.getRFSS() );
sb.append( "\nSITE:\t" + neighbor.getSiteID() );
sb.append( "\nPCCH:\tDNLINK " + neighbor.getDownlinkFrequency() +
String neighborID = neighbor.getRFSS() + "-" + neighbor.getSiteID();
sb.append( "\nRFSS-SITE:\t" + neighborID );
if( mAliasList != null )
{
Alias siteAlias = mAliasList.getSiteID( neighborID );
if( siteAlias != null )
{
sb.append( " " + siteAlias.getName() );
}
}
sb.append( "\nPCCH:\tDNLINK " + mFrequencyFormatter.format(
(double)neighbor.getDownlinkFrequency() / 1E6d ) +
" [" + neighbor.getIdentifier() + "-" + neighbor.getChannel() + "]" );
sb.append( "\n\tUPLINK:" + neighbor.getUplinkFrequency() + "\n" );
sb.append( "\n\tUPLINK:" + mFrequencyFormatter.format(
(double)neighbor.getUplinkFrequency() / 1E6d ) + "\n" );
sb.append( "\nSERVICES:\t" + Service.getServices( neighbor.getSystemServiceClass() ) );
sb.append( "\n----------------------------------------------------" );
}

View File

@@ -60,7 +60,7 @@ public class P25Decoder extends Decoder implements Instrumentable
super( sampleType );
mAliasList = aliasList;
/**
* Only setup a demod chain if we're receiving complex samples. If
* we're receiving demodulated samples, they'll be handled the same

View File

@@ -36,30 +36,33 @@ public class P25MessageProcessor implements Listener<Message>
@Override
public void receive( Message message )
{
/* Insert band identifier update messages into channel-type messages */
if( message instanceof IdentifierUpdateReceiver )
if( message.isValid() )
{
IdentifierUpdateReceiver receiver = (IdentifierUpdateReceiver)message;
int[] identifiers = receiver.getIdentifiers();
for( int identifier: identifiers )
/* Insert band identifier update messages into channel-type messages */
if( message instanceof IdentifierUpdateReceiver )
{
receiver.setIdentifierMessage( identifier,
mIdentifierMap.get( identifier ) );
IdentifierUpdateReceiver receiver = (IdentifierUpdateReceiver)message;
int[] identifiers = receiver.getIdentifiers();
for( int identifier: identifiers )
{
receiver.setIdentifierMessage( identifier,
mIdentifierMap.get( identifier ) );
}
}
}
/* Store band identifiers so that they can be injected into channel
* type messages */
if( message instanceof IdentifierUpdate )
{
IdentifierUpdate identifierUpdate = (IdentifierUpdate)message;
/* Store band identifiers so that they can be injected into channel
* type messages */
if( message instanceof IdentifierUpdate )
{
IdentifierUpdate identifierUpdate = (IdentifierUpdate)message;
mIdentifierMap.put( identifierUpdate.getIdentifier(), identifierUpdate );
}
mIdentifierMap.put( identifierUpdate.getIdentifier(), identifierUpdate );
mBroadcaster.broadcast( message );
}
mBroadcaster.broadcast( message );
}
public void dispose()

View File

@@ -143,7 +143,18 @@ public class P25Message extends Message
@Override
public boolean isValid()
{
return true;
if( mCRC != null )
{
for( CRC crc: mCRC )
{
if( crc == CRC.FAILED_CRC )
{
return false;
}
}
}
return true;
}
/**

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.tsbk.osp.control.IdentifierUpdate;
@@ -45,6 +46,10 @@ public abstract class UnitToUnitChannelGrantExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
public String getMessage()

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -37,6 +38,10 @@ public class AdjacentStatusBroadcastExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -24,6 +25,10 @@ public class CallAlertExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -24,6 +25,10 @@ public class GroupAffiliationQueryExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -34,6 +35,10 @@ public class GroupAffiliationResponseExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -26,6 +27,10 @@ public class MessageUpdateExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -36,6 +37,10 @@ public class NetworkStatusBroadcastExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -38,6 +39,10 @@ public class ProtectionParameterBroadcast extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -37,6 +38,10 @@ public class RFSSStatusBroadcastExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -69,18 +70,34 @@ public class RoamingAddressUpdateExtended extends PDUMessage
if( mMessage.size() == P25MessageFramer.PDU2_BEGIN )
{
mFormat = Format.FORMAT_1;
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
else if( mMessage.size() == P25MessageFramer.PDU3_BEGIN )
{
mFormat = Format.FORMAT_2;
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
else if( mMessage.size() == P25MessageFramer.PDU3_DECODED_END )
{
mFormat = Format.FORMAT_3;
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU3( mMessage );
}
else
{
mFormat = Format.FORMAT_1;
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
}

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -24,6 +25,10 @@ public class StatusQueryExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -26,6 +27,10 @@ public class StatusUpdateExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.control;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -28,6 +29,10 @@ public class UnitRegistrationResponseExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
@Override

View File

@@ -2,6 +2,7 @@ package decode.p25.message.pdu.osp.data;
import java.util.Date;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -42,6 +43,10 @@ public class GroupDataChannelGrantExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.voice;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -40,6 +41,10 @@ public class GroupVoiceChannelGrantExplicit extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -2,6 +2,7 @@ package decode.p25.message.pdu.osp.voice;
import java.util.Date;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -42,6 +43,10 @@ public class TelephoneInterconnectChannelGrantExplicit extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.voice;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -30,6 +31,10 @@ public class UnitToUnitAnswerRequestExplicit extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU1( mMessage );
}
@Override

View File

@@ -1,5 +1,6 @@
package decode.p25.message.pdu.osp.voice;
import crc.CRCP25;
import alias.AliasList;
import bits.BitSetBuffer;
import decode.p25.message.pdu.PDUMessage;
@@ -46,6 +47,10 @@ public class UnitToUnitVoiceChannelGrantUpdateExtended extends PDUMessage
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mCRC[ 1 ] = CRCP25.correctPDU2( mMessage );
}
@Override