package module.decode.p25.message.pdu.osp.control;
import module.decode.p25.P25MessageFramer;
import module.decode.p25.message.pdu.PDUMessage;
import module.decode.p25.reference.DataUnitID;
import module.decode.p25.reference.Opcode;
import alias.AliasList;
import bits.BinaryMessage;
import edac.CRCP25;
public class RoamingAddressUpdateExtended extends PDUMessage
{
public static final int[] TARGET_ADDRESS = { 88,89,90,91,92,93,94,95,96,97,
98,99,100,101,102,103,104,105,106,107,108,109,110,111 };
public static final int LAST_MESSAGE_INDICATOR = 128;
public static final int[] MESSAGE_SEQUENCE_NUMBER = { 132,133,134,135 };
public static final int[] WACN_A = { 136,137,138,139,140,141,142,143,160,
161,162,163,164,165,166,167,168,169,170,171 };
public static final int[] SYSTEM_ID_A = { 172,173,174,175,176,177,178,179,
180,181,182,183 };
public static final int[] SOURCE_ID_FORMAT_1 = { 184,185,186,187,188,189,
190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207 };
public static final int[] WACN_B = { 184,185,186,187,188,189,190,191,192,
193,194,195,196,197,198,199,200,201,202,203 };
public static final int[] SYSTEM_ID_B = { 204,205,206,207,208,209,210,211,
212,213,214,215 };
public static final int[] WACN_C = { 216,217,218,219,220,221,222,223,224,
225,226,227,228,229,230,231,232,233,234,235 };
public static final int[] SYSTEM_ID_C = { 236,237,238,239,240,241,242,243,
244,245,246,247 };
public static final int[] WACN_D = { 248,249,250,251,252,253,254,255,256,
257,258,259,260,261,262,263,264,265,266,267 };
public static final int[] SYSTEM_ID_D = { 268,269,270,271,272,273,274,275,
276,277,278,279 };
public static final int[] SOURCE_ID_FORMAT_2 = { 280,281,282,283,284,285,
286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303 };
public static final int[] WACN_E = { 280,281,282,283,284,285,
286,287,288,289,290,291,292,293,294,295,296,297,298,299 };
public static final int[] SYSTEM_ID_E = { 300,301,302,303,304,305,306,307,
308,309,310,311 };
public static final int[] WACN_F = { 312,313,314,315,316,317,318,319,320,
321,322,323,324,325,326,327,328,329,330,331 };
public static final int[] SYSTEM_ID_F = { 332,333,334,335,336,337,338,339,
340,341,342,343 };
public static final int[] WACN_G = { 344,345,346,347,348,349,350,351,352,
353,354,355,356,357,358,359,360,361,362,363 };
public static final int[] SYSTEM_ID_G = { 364,365,366,367,368,369,370,371,
372,373,374,375 };
public static final int[] SOURCE_ID_FORMAT_3 = { 376,377,378,379,380,381,
382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399 };
public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_1 = { 224,225,226,227,
228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
246,247,248,249,250,251,252,253,254,255 };
public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_2 = { 320,321,322,323,
324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,
342,343,344,345,346,347,348,349,350,351 };
public static final int[] MULTIPLE_BLOCK_CRC_FORMAT_3 = { 416,417,418,419,
420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,
438,439,440,441,442,443,444,445,446,447 };
private enum Format{ FORMAT_1, FORMAT_2, FORMAT_3 };
private Format mFormat;
public RoamingAddressUpdateExtended( BinaryMessage message,
DataUnitID duid, AliasList aliasList )
{
super( message, duid, aliasList );
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 */
mMessage = CRCP25.correctPDU1( mMessage );
mCRC[ 1 ] = mMessage.getCRC();
}
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 */
mMessage = CRCP25.correctPDU2( mMessage );
mCRC[ 1 ] = mMessage.getCRC();
}
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 */
mMessage = CRCP25.correctPDU3( mMessage );
mCRC[ 1 ] = mMessage.getCRC();
}
else
{
mFormat = Format.FORMAT_1;
/* Header block is already error detected/corrected - perform error
* detection correction on the intermediate and final data blocks */
mMessage = CRCP25.correctPDU1( mMessage );
mCRC[ 1 ] = mMessage.getCRC();
}
}
@Override
public String getEventType()
{
return Opcode.ROAMING_ADDRESS_UPDATE.getDescription();
}
public String getMessage()
{
StringBuilder sb = new StringBuilder();
sb.append( getMessageStub() );
sb.append( " ROAMING ADDRESS STACK FROM:" );
sb.append( getSourceID() );
if( isLastBlock() )
{
sb.append( " LAST BLOCK" );
}
sb.append( "MSG SEQ:" );
sb.append( getMessageSequenceNumber() );
sb.append( " TO:" );
sb.append( getTargetAddress() );
sb.append( " WACN A:" + getWACNA() );
sb.append( " SYS A:" + getSystemIDA() );
if( isFormat2() )
{
sb.append( " WACN B:" + getWACNB() );
sb.append( " SYS B:" + getSystemIDB() );
sb.append( " WACN C:" + getWACNC() );
sb.append( " SYS C:" + getSystemIDC() );
sb.append( " WACN D:" + getWACND() );
sb.append( " SYS D:" + getSystemIDD() );
}
if( isFormat3() )
{
sb.append( " WACN E:" + getWACNE() );
sb.append( " SYS E:" + getSystemIDE() );
sb.append( " WACN F:" + getWACNF() );
sb.append( " SYS F:" + getSystemIDF() );
sb.append( " WACN G:" + getWACNG() );
sb.append( " SYS G:" + getSystemIDG() );
}
return sb.toString();
}
public boolean isLastBlock()
{
return mMessage.get( LAST_MESSAGE_INDICATOR );
}
public int getMessageSequenceNumber()
{
return mMessage.getInt( MESSAGE_SEQUENCE_NUMBER );
}
public String getTargetAddress()
{
return mMessage.getHex( TARGET_ADDRESS, 6 );
}
public String getWACNA()
{
return mMessage.getHex( WACN_A, 5 );
}
public String getSystemIDA()
{
return mMessage.getHex( SYSTEM_ID_A, 3 );
}
public String getWACNB()
{
return isFormat2() ? mMessage.getHex( WACN_B, 5 ) : null;
}
public String getSystemIDB()
{
return isFormat2() ? mMessage.getHex( SYSTEM_ID_B, 3 ) : null;
}
public String getWACNC()
{
return isFormat2() ? mMessage.getHex( WACN_C, 5 ) : null;
}
public String getSystemIDC()
{
return isFormat2() ? mMessage.getHex( SYSTEM_ID_C, 3 ) : null;
}
public String getWACND()
{
return isFormat2() ? mMessage.getHex( WACN_D, 5 ) : null;
}
public String getSystemIDD()
{
return isFormat2() ? mMessage.getHex( SYSTEM_ID_D, 3 ) : null;
}
public String getWACNE()
{
return isFormat3() ? mMessage.getHex( WACN_E, 5 ) : null;
}
public String getSystemIDE()
{
return isFormat3() ? mMessage.getHex( SYSTEM_ID_E, 3 ) : null;
}
public String getWACNF()
{
return isFormat3() ? mMessage.getHex( WACN_F, 5 ) : null;
}
public String getSystemIDF()
{
return isFormat3() ? mMessage.getHex( SYSTEM_ID_F, 3 ) : null;
}
public String getWACNG()
{
return isFormat3() ? mMessage.getHex( WACN_G, 5 ) : null;
}
public String getSystemIDG()
{
return isFormat3() ? mMessage.getHex( SYSTEM_ID_G, 3 ) : null;
}
public String getSourceID()
{
switch( mFormat )
{
case FORMAT_1:
return mMessage.getHex( SOURCE_ID_FORMAT_1, 6 );
case FORMAT_2:
return mMessage.getHex( SOURCE_ID_FORMAT_2, 6 );
case FORMAT_3:
return mMessage.getHex( SOURCE_ID_FORMAT_2, 6 );
}
return null;
}
public boolean isFormat2()
{
return mFormat != Format.FORMAT_3;
}
public boolean isFormat3()
{
return mFormat == Format.FORMAT_3;
}
}