Home | History | Annotate | Download | only in gsm
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.telephony.gsm;
     18 
     19 import android.telephony.SmsCbCmasInfo;
     20 import android.telephony.SmsCbEtwsInfo;
     21 
     22 import java.util.Arrays;
     23 
     24 /**
     25  * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by
     26  * CellBroadcastReceiver test cases, but should not be used by applications.
     27  *
     28  * All relevant header information is now sent as a Parcelable
     29  * {@link android.telephony.SmsCbMessage} object in the "message" extra of the
     30  * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or
     31  * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent.
     32  * The raw PDU is no longer sent to SMS CB applications.
     33  */
     34 public class SmsCbHeader {
     35 
     36     /**
     37      * Length of SMS-CB header
     38      */
     39     static final int PDU_HEADER_LENGTH = 6;
     40 
     41     /**
     42      * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
     43      */
     44     static final int FORMAT_GSM = 1;
     45 
     46     /**
     47      * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
     48      */
     49     static final int FORMAT_UMTS = 2;
     50 
     51     /**
     52      * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
     53      */
     54     static final int FORMAT_ETWS_PRIMARY = 3;
     55 
     56     /**
     57      * Message type value as defined in 3gpp TS 25.324, section 11.1.
     58      */
     59     private static final int MESSAGE_TYPE_CBS_MESSAGE = 1;
     60 
     61     /**
     62      * Length of GSM pdus
     63      */
     64     private static final int PDU_LENGTH_GSM = 88;
     65 
     66     /**
     67      * Maximum length of ETWS primary message GSM pdus
     68      */
     69     private static final int PDU_LENGTH_ETWS = 56;
     70 
     71     private final int mGeographicalScope;
     72 
     73     /** The serial number combines geographical scope, message code, and update number. */
     74     private final int mSerialNumber;
     75 
     76     /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */
     77     private final int mMessageIdentifier;
     78 
     79     private final int mDataCodingScheme;
     80 
     81     private final int mPageIndex;
     82 
     83     private final int mNrOfPages;
     84 
     85     private final int mFormat;
     86 
     87     /** ETWS warning notification info. */
     88     private final SmsCbEtwsInfo mEtwsInfo;
     89 
     90     /** CMAS warning notification info. */
     91     private final SmsCbCmasInfo mCmasInfo;
     92 
     93     public SmsCbHeader(byte[] pdu) throws IllegalArgumentException {
     94         if (pdu == null || pdu.length < PDU_HEADER_LENGTH) {
     95             throw new IllegalArgumentException("Illegal PDU");
     96         }
     97 
     98         if (pdu.length <= PDU_LENGTH_GSM) {
     99             // can be ETWS or GSM format.
    100             // Per TS23.041 9.4.1.2 and 9.4.1.3.2, GSM and ETWS format both
    101             // contain serial number which contains GS, Message Code, and Update Number
    102             // per 9.4.1.2.1, and message identifier in same octets
    103             mGeographicalScope = (pdu[0] & 0xc0) >>> 6;
    104             mSerialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff);
    105             mMessageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff);
    106             if (isEtwsMessage() && pdu.length <= PDU_LENGTH_ETWS) {
    107                 mFormat = FORMAT_ETWS_PRIMARY;
    108                 mDataCodingScheme = -1;
    109                 mPageIndex = -1;
    110                 mNrOfPages = -1;
    111                 boolean emergencyUserAlert = (pdu[4] & 0x1) != 0;
    112                 boolean activatePopup = (pdu[5] & 0x80) != 0;
    113                 int warningType = (pdu[4] & 0xfe) >>> 1;
    114                 byte[] warningSecurityInfo;
    115                 // copy the Warning-Security-Information, if present
    116                 if (pdu.length > PDU_HEADER_LENGTH) {
    117                     warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length);
    118                 } else {
    119                     warningSecurityInfo = null;
    120                 }
    121                 mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup,
    122                         true, warningSecurityInfo);
    123                 mCmasInfo = null;
    124                 return;     // skip the ETWS/CMAS initialization code for regular notifications
    125             } else {
    126                 // GSM pdus are no more than 88 bytes
    127                 mFormat = FORMAT_GSM;
    128                 mDataCodingScheme = pdu[4] & 0xff;
    129 
    130                 // Check for invalid page parameter
    131                 int pageIndex = (pdu[5] & 0xf0) >>> 4;
    132                 int nrOfPages = pdu[5] & 0x0f;
    133 
    134                 if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) {
    135                     pageIndex = 1;
    136                     nrOfPages = 1;
    137                 }
    138 
    139                 mPageIndex = pageIndex;
    140                 mNrOfPages = nrOfPages;
    141             }
    142         } else {
    143             // UMTS pdus are always at least 90 bytes since the payload includes
    144             // a number-of-pages octet and also one length octet per page
    145             mFormat = FORMAT_UMTS;
    146 
    147             int messageType = pdu[0];
    148 
    149             if (messageType != MESSAGE_TYPE_CBS_MESSAGE) {
    150                 throw new IllegalArgumentException("Unsupported message type " + messageType);
    151             }
    152 
    153             mMessageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff;
    154             mGeographicalScope = (pdu[3] & 0xc0) >>> 6;
    155             mSerialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff);
    156             mDataCodingScheme = pdu[5] & 0xff;
    157 
    158             // We will always consider a UMTS message as having one single page
    159             // since there's only one instance of the header, even though the
    160             // actual payload may contain several pages.
    161             mPageIndex = 1;
    162             mNrOfPages = 1;
    163         }
    164 
    165         if (isEtwsMessage()) {
    166             boolean emergencyUserAlert = isEtwsEmergencyUserAlert();
    167             boolean activatePopup = isEtwsPopupAlert();
    168             int warningType = getEtwsWarningType();
    169             mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup,
    170                     false, null);
    171             mCmasInfo = null;
    172         } else if (isCmasMessage()) {
    173             int messageClass = getCmasMessageClass();
    174             int severity = getCmasSeverity();
    175             int urgency = getCmasUrgency();
    176             int certainty = getCmasCertainty();
    177             mEtwsInfo = null;
    178             mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN,
    179                     SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty);
    180         } else {
    181             mEtwsInfo = null;
    182             mCmasInfo = null;
    183         }
    184     }
    185 
    186     int getGeographicalScope() {
    187         return mGeographicalScope;
    188     }
    189 
    190     int getSerialNumber() {
    191         return mSerialNumber;
    192     }
    193 
    194     int getServiceCategory() {
    195         return mMessageIdentifier;
    196     }
    197 
    198     int getDataCodingScheme() {
    199         return mDataCodingScheme;
    200     }
    201 
    202     int getPageIndex() {
    203         return mPageIndex;
    204     }
    205 
    206     int getNumberOfPages() {
    207         return mNrOfPages;
    208     }
    209 
    210     SmsCbEtwsInfo getEtwsInfo() {
    211         return mEtwsInfo;
    212     }
    213 
    214     SmsCbCmasInfo getCmasInfo() {
    215         return mCmasInfo;
    216     }
    217 
    218     /**
    219      * Return whether this broadcast is an emergency (PWS) message type.
    220      * @return true if this message is emergency type; false otherwise
    221      */
    222     boolean isEmergencyMessage() {
    223         return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
    224                 && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
    225     }
    226 
    227     /**
    228      * Return whether this broadcast is an ETWS emergency message type.
    229      * @return true if this message is ETWS emergency type; false otherwise
    230      */
    231     private boolean isEtwsMessage() {
    232         return (mMessageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK)
    233                 == SmsCbConstants.MESSAGE_ID_ETWS_TYPE;
    234     }
    235 
    236     /**
    237      * Return whether this broadcast is an ETWS primary notification.
    238      * @return true if this message is an ETWS primary notification; false otherwise
    239      */
    240     boolean isEtwsPrimaryNotification() {
    241         return mFormat == FORMAT_ETWS_PRIMARY;
    242     }
    243 
    244     /**
    245      * Return whether this broadcast is in UMTS format.
    246      * @return true if this message is in UMTS format; false otherwise
    247      */
    248     boolean isUmtsFormat() {
    249         return mFormat == FORMAT_UMTS;
    250     }
    251 
    252     /**
    253      * Return whether this message is a CMAS emergency message type.
    254      * @return true if this message is CMAS emergency type; false otherwise
    255      */
    256     private boolean isCmasMessage() {
    257         return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER
    258                 && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER;
    259     }
    260 
    261     /**
    262      * Return whether the popup alert flag is set for an ETWS warning notification.
    263      * This method assumes that the message ID has already been checked for ETWS type.
    264      *
    265      * @return true if the message code indicates a popup alert should be displayed
    266      */
    267     private boolean isEtwsPopupAlert() {
    268         return (mSerialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0;
    269     }
    270 
    271     /**
    272      * Return whether the emergency user alert flag is set for an ETWS warning notification.
    273      * This method assumes that the message ID has already been checked for ETWS type.
    274      *
    275      * @return true if the message code indicates an emergency user alert
    276      */
    277     private boolean isEtwsEmergencyUserAlert() {
    278         return (mSerialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0;
    279     }
    280 
    281     /**
    282      * Returns the warning type for an ETWS warning notification.
    283      * This method assumes that the message ID has already been checked for ETWS type.
    284      *
    285      * @return the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24
    286      */
    287     private int getEtwsWarningType() {
    288         return mMessageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING;
    289     }
    290 
    291     /**
    292      * Returns the message class for a CMAS warning notification.
    293      * This method assumes that the message ID has already been checked for CMAS type.
    294      * @return the CMAS message class as defined in {@link SmsCbCmasInfo}
    295      */
    296     private int getCmasMessageClass() {
    297         switch (mMessageIdentifier) {
    298             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL:
    299             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE:
    300                 return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT;
    301 
    302             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
    303             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE:
    304             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
    305             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE:
    306                 return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT;
    307 
    308             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
    309             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE:
    310             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
    311             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE:
    312             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
    313             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE:
    314             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
    315             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE:
    316             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
    317             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE:
    318             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
    319             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE:
    320                 return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT;
    321 
    322             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY:
    323             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE:
    324                 return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY;
    325 
    326             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST:
    327             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE:
    328                 return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST;
    329 
    330             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE:
    331             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE:
    332                 return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE;
    333 
    334             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE:
    335             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE:
    336                 return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE;
    337 
    338             default:
    339                 return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
    340         }
    341     }
    342 
    343     /**
    344      * Returns the severity for a CMAS warning notification. This is only available for extreme
    345      * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
    346      * This method assumes that the message ID has already been checked for CMAS type.
    347      * @return the CMAS severity as defined in {@link SmsCbCmasInfo}
    348      */
    349     private int getCmasSeverity() {
    350         switch (mMessageIdentifier) {
    351             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
    352             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE:
    353             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
    354             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE:
    355             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
    356             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE:
    357             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
    358             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE:
    359                 return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME;
    360 
    361             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
    362             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE:
    363             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
    364             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE:
    365             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
    366             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE:
    367             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
    368             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE:
    369                 return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE;
    370 
    371             default:
    372                 return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
    373         }
    374     }
    375 
    376     /**
    377      * Returns the urgency for a CMAS warning notification. This is only available for extreme
    378      * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
    379      * This method assumes that the message ID has already been checked for CMAS type.
    380      * @return the CMAS urgency as defined in {@link SmsCbCmasInfo}
    381      */
    382     private int getCmasUrgency() {
    383         switch (mMessageIdentifier) {
    384             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
    385             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE:
    386             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
    387             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE:
    388             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
    389             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE:
    390             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
    391             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE:
    392                 return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE;
    393 
    394             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
    395             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE:
    396             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
    397             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE:
    398             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
    399             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE:
    400             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
    401             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE:
    402                 return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED;
    403 
    404             default:
    405                 return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
    406         }
    407     }
    408 
    409     /**
    410      * Returns the certainty for a CMAS warning notification. This is only available for extreme
    411      * and severe alerts, not for other types such as Presidential Level and AMBER alerts.
    412      * This method assumes that the message ID has already been checked for CMAS type.
    413      * @return the CMAS certainty as defined in {@link SmsCbCmasInfo}
    414      */
    415     private int getCmasCertainty() {
    416         switch (mMessageIdentifier) {
    417             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED:
    418             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE:
    419             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED:
    420             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE:
    421             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED:
    422             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE:
    423             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED:
    424             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE:
    425                 return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED;
    426 
    427             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY:
    428             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE:
    429             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY:
    430             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE:
    431             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY:
    432             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE:
    433             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY:
    434             case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE:
    435                 return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY;
    436 
    437             default:
    438                 return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
    439         }
    440     }
    441 
    442     @Override
    443     public String toString() {
    444         return "SmsCbHeader{GS=" + mGeographicalScope + ", serialNumber=0x"
    445                 + Integer.toHexString(mSerialNumber)
    446                 + ", messageIdentifier=0x" + Integer.toHexString(mMessageIdentifier)
    447                 + ", format=" + mFormat
    448                 + ", DCS=0x" + Integer.toHexString(mDataCodingScheme)
    449                 + ", page " + mPageIndex + " of " + mNrOfPages + '}';
    450     }
    451 }