FileDocCategorySizeDatePackage
SmsCbHeader.javaAPI DocAndroid 5.1 API16487Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony.gsm

SmsCbHeader

public class SmsCbHeader extends Object
Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by CellBroadcastReceiver test cases, but should not be used by applications. All relevant header information is now sent as a Parcelable {@link android.telephony.SmsCbMessage} object in the "message" extra of the {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent. The raw PDU is no longer sent to SMS CB applications.

Fields Summary
static final int
PDU_HEADER_LENGTH
Length of SMS-CB header
static final int
FORMAT_GSM
GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
static final int
FORMAT_UMTS
UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
static final int
FORMAT_ETWS_PRIMARY
GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
private static final int
MESSAGE_TYPE_CBS_MESSAGE
Message type value as defined in 3gpp TS 25.324, section 11.1.
private static final int
PDU_LENGTH_GSM
Length of GSM pdus
private static final int
PDU_LENGTH_ETWS
Maximum length of ETWS primary message GSM pdus
private final int
mGeographicalScope
private final int
mSerialNumber
The serial number combines geographical scope, message code, and update number.
private final int
mMessageIdentifier
The Message Identifier in 3GPP is the same as the Service Category in CDMA.
private final int
mDataCodingScheme
private final int
mPageIndex
private final int
mNrOfPages
private final int
mFormat
private final android.telephony.SmsCbEtwsInfo
mEtwsInfo
ETWS warning notification info.
private final android.telephony.SmsCbCmasInfo
mCmasInfo
CMAS warning notification info.
Constructors Summary
public SmsCbHeader(byte[] pdu)


         
        if (pdu == null || pdu.length < PDU_HEADER_LENGTH) {
            throw new IllegalArgumentException("Illegal PDU");
        }

        if (pdu.length <= PDU_LENGTH_GSM) {
            // can be ETWS or GSM format.
            // Per TS23.041 9.4.1.2 and 9.4.1.3.2, GSM and ETWS format both
            // contain serial number which contains GS, Message Code, and Update Number
            // per 9.4.1.2.1, and message identifier in same octets
            mGeographicalScope = (pdu[0] & 0xc0) >>> 6;
            mSerialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
            mMessageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
            if (isEtwsMessage() && pdu.length <= PDU_LENGTH_ETWS) {
                mFormat = FORMAT_ETWS_PRIMARY;
                mDataCodingScheme = -1;
                mPageIndex = -1;
                mNrOfPages = -1;
                boolean emergencyUserAlert = (pdu[4] & 0x1) != 0;
                boolean activatePopup = (pdu[5] & 0x80) != 0;
                int warningType = (pdu[4] & 0xfe) >>> 1;
                byte[] warningSecurityInfo;
                // copy the Warning-Security-Information, if present
                if (pdu.length > PDU_HEADER_LENGTH) {
                    warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length);
                } else {
                    warningSecurityInfo = null;
                }
                mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup,
                        warningSecurityInfo);
                mCmasInfo = null;
                return;     // skip the ETWS/CMAS initialization code for regular notifications
            } else {
                // GSM pdus are no more than 88 bytes
                mFormat = FORMAT_GSM;
                mDataCodingScheme = pdu[4] & 0xff;

                // Check for invalid page parameter
                int pageIndex = (pdu[5] & 0xf0) >>> 4;
                int nrOfPages = pdu[5] & 0x0f;

                if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) {
                    pageIndex = 1;
                    nrOfPages = 1;
                }

                mPageIndex = pageIndex;
                mNrOfPages = nrOfPages;
            }
        } else {
            // UMTS pdus are always at least 90 bytes since the payload includes
            // a number-of-pages octet and also one length octet per page
            mFormat = FORMAT_UMTS;

            int messageType = pdu[0];

            if (messageType != MESSAGE_TYPE_CBS_MESSAGE) {
                throw new IllegalArgumentException("Unsupported message type " + messageType);
            }

            mMessageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff;
            mGeographicalScope = (pdu[3] & 0xc0) >>> 6;
            mSerialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff);
            mDataCodingScheme = pdu[5] & 0xff;

            // We will always consider a UMTS message as having one single page
            // since there's only one instance of the header, even though the
            // actual payload may contain several pages.
            mPageIndex = 1;
            mNrOfPages = 1;
        }

        if (isEtwsMessage()) {
            boolean emergencyUserAlert = isEtwsEmergencyUserAlert();
            boolean activatePopup = isEtwsPopupAlert();
            int warningType = getEtwsWarningType();
            mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, null);
            mCmasInfo = null;
        } else if (isCmasMessage()) {
            int messageClass = getCmasMessageClass();
            int severity = getCmasSeverity();
            int urgency = getCmasUrgency();
            int certainty = getCmasCertainty();
            mEtwsInfo = null;
            mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN,
                    SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty);
        } else {
            mEtwsInfo = null;
            mCmasInfo = null;
        }
    
Methods Summary
private intgetCmasCertainty()
Returns the certainty for a CMAS warning notification. This is only available for extreme and severe alerts, not for other types such as Presidential Level and AMBER alerts. This method assumes that the message ID has already been checked for CMAS type.

return
the CMAS certainty as defined in {@link SmsCbCmasInfo}

        switch (mMessageIdentifier) {
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
                return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
                return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY;

            default:
                return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
        }
    
android.telephony.SmsCbCmasInfogetCmasInfo()

        return mCmasInfo;
    
private intgetCmasMessageClass()
Returns the message class for a CMAS warning notification. This method assumes that the message ID has already been checked for CMAS type.

return
the CMAS message class as defined in {@link SmsCbCmasInfo}

        switch (mMessageIdentifier) {
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL:
                return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
                return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
                return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY:
                return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST:
                return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE:
                return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE:
                return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE;

            default:
                return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
        }
    
private intgetCmasSeverity()
Returns the severity for a CMAS warning notification. This is only available for extreme and severe alerts, not for other types such as Presidential Level and AMBER alerts. This method assumes that the message ID has already been checked for CMAS type.

return
the CMAS severity as defined in {@link SmsCbCmasInfo}

        switch (mMessageIdentifier) {
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
                return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
                return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE;

            default:
                return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
        }
    
private intgetCmasUrgency()
Returns the urgency for a CMAS warning notification. This is only available for extreme and severe alerts, not for other types such as Presidential Level and AMBER alerts. This method assumes that the message ID has already been checked for CMAS type.

return
the CMAS urgency as defined in {@link SmsCbCmasInfo}

        switch (mMessageIdentifier) {
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
                return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE;

            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
            case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
                return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED;

            default:
                return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
        }
    
intgetDataCodingScheme()

        return mDataCodingScheme;
    
android.telephony.SmsCbEtwsInfogetEtwsInfo()

        return mEtwsInfo;
    
private intgetEtwsWarningType()
Returns the warning type for an ETWS warning notification. This method assumes that the message ID has already been checked for ETWS type.

return
the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24

        return mMessageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING;
    
intgetGeographicalScope()

        return mGeographicalScope;
    
intgetNumberOfPages()

        return mNrOfPages;
    
intgetPageIndex()

        return mPageIndex;
    
intgetSerialNumber()

        return mSerialNumber;
    
intgetServiceCategory()

        return mMessageIdentifier;
    
private booleanisCmasMessage()
Return whether this message is a CMAS emergency message type.

return
true if this message is CMAS emergency type; false otherwise

        return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER
                && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER;
    
booleanisEmergencyMessage()
Return whether this broadcast is an emergency (PWS) message type.

return
true if this message is emergency type; false otherwise

        return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
                && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
    
private booleanisEtwsEmergencyUserAlert()
Return whether the emergency user alert flag is set for an ETWS warning notification. This method assumes that the message ID has already been checked for ETWS type.

return
true if the message code indicates an emergency user alert

        return (mSerialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0;
    
private booleanisEtwsMessage()
Return whether this broadcast is an ETWS emergency message type.

return
true if this message is ETWS emergency type; false otherwise

        return (mMessageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK)
                == SmsCbConstants.MESSAGE_ID_ETWS_TYPE;
    
private booleanisEtwsPopupAlert()
Return whether the popup alert flag is set for an ETWS warning notification. This method assumes that the message ID has already been checked for ETWS type.

return
true if the message code indicates a popup alert should be displayed

        return (mSerialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0;
    
booleanisEtwsPrimaryNotification()
Return whether this broadcast is an ETWS primary notification.

return
true if this message is an ETWS primary notification; false otherwise

        return mFormat == FORMAT_ETWS_PRIMARY;
    
booleanisUmtsFormat()
Return whether this broadcast is in UMTS format.

return
true if this message is in UMTS format; false otherwise

        return mFormat == FORMAT_UMTS;
    
public java.lang.StringtoString()

        return "SmsCbHeader{GS=" + mGeographicalScope + ", serialNumber=0x" +
                Integer.toHexString(mSerialNumber) +
                ", messageIdentifier=0x" + Integer.toHexString(mMessageIdentifier) +
                ", DCS=0x" + Integer.toHexString(mDataCodingScheme) +
                ", page " + mPageIndex + " of " + mNrOfPages + '}";