Home | History | Annotate | Download | only in telephony
      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 android.telephony;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 /**
     23  * Parcelable object containing a received cell broadcast message. There are four different types
     24  * of Cell Broadcast messages:
     25  *
     26  * <ul>
     27  * <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li>
     28  * <li>cell information messages, broadcast on channel 50, indicating the current cell name for
     29  *  roaming purposes (required to display on the idle screen in Brazil)</li>
     30  * <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li>
     31  * <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li>
     32  * </ul>
     33  *
     34  * <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only),
     35  * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were
     36  * unified under a common name, avoiding some names, such as "Message Identifier", that refer to
     37  * two completely different concepts in 3GPP and CDMA.
     38  *
     39  * <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name
     40  * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP
     41  * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the
     42  * application should
     43  *
     44  * <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used
     45  * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is
     46  * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit
     47  * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number
     48  * are considered unique to the PLMN, to the current cell, or to the current Location Area (or
     49  * Service Area in UMTS). The relevant values are concatenated into a single String which will be
     50  * unique if the messages are not duplicates.
     51  *
     52  * <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the
     53  * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object.
     54  *
     55  * <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive
     56  * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts.
     57  * Only system applications such as the CellBroadcastReceiver may receive notifications for
     58  * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or
     59  * interference with the immediate display of the alert message and playing of the alert sound and
     60  * vibration pattern, which could be caused by poorly written or malicious non-system code.
     61  *
     62  * @hide
     63  */
     64 public class SmsCbMessage implements Parcelable {
     65 
     66     protected static final String LOG_TAG = "SMSCB";
     67 
     68     /** Cell wide geographical scope with immediate display (GSM/UMTS only). */
     69     public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
     70 
     71     /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */
     72     public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
     73 
     74     /** Location / service area wide geographical scope (GSM/UMTS only). */
     75     public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2;
     76 
     77     /** Cell wide geographical scope (GSM/UMTS only). */
     78     public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
     79 
     80     /** GSM or UMTS format cell broadcast. */
     81     public static final int MESSAGE_FORMAT_3GPP = 1;
     82 
     83     /** CDMA format cell broadcast. */
     84     public static final int MESSAGE_FORMAT_3GPP2 = 2;
     85 
     86     /** Normal message priority. */
     87     public static final int MESSAGE_PRIORITY_NORMAL = 0;
     88 
     89     /** Interactive message priority. */
     90     public static final int MESSAGE_PRIORITY_INTERACTIVE = 1;
     91 
     92     /** Urgent message priority. */
     93     public static final int MESSAGE_PRIORITY_URGENT = 2;
     94 
     95     /** Emergency message priority. */
     96     public static final int MESSAGE_PRIORITY_EMERGENCY = 3;
     97 
     98     /** Format of this message (for interpretation of service category values). */
     99     private final int mMessageFormat;
    100 
    101     /** Geographical scope of broadcast. */
    102     private final int mGeographicalScope;
    103 
    104     /**
    105      * Serial number of broadcast (message identifier for CDMA, geographical scope + message code +
    106      * update number for GSM/UMTS). The serial number plus the location code uniquely identify
    107      * a cell broadcast for duplicate detection.
    108      */
    109     private final int mSerialNumber;
    110 
    111     /**
    112      * Location identifier for this message. It consists of the current operator MCC/MNC as a
    113      * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
    114      * message is not binary 01, the Location Area is included for comparison. If the GS is
    115      * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified.
    116      */
    117     private final SmsCbLocation mLocation;
    118 
    119     /**
    120      * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings,
    121      * the information provided by the category is also available via {@link #getEtwsWarningInfo()}
    122      * or {@link #getCmasWarningInfo()}.
    123      */
    124     private final int mServiceCategory;
    125 
    126     /** Message language, as a two-character string, e.g. "en". */
    127     private final String mLanguage;
    128 
    129     /** Message body, as a String. */
    130     private final String mBody;
    131 
    132     /** Message priority (including emergency priority). */
    133     private final int mPriority;
    134 
    135     /** ETWS warning notification information (ETWS warnings only). */
    136     private final SmsCbEtwsInfo mEtwsWarningInfo;
    137 
    138     /** CMAS warning notification information (CMAS warnings only). */
    139     private final SmsCbCmasInfo mCmasWarningInfo;
    140 
    141     /**
    142      * Create a new SmsCbMessage with the specified data.
    143      */
    144     public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
    145             SmsCbLocation location, int serviceCategory, String language, String body,
    146             int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {
    147         mMessageFormat = messageFormat;
    148         mGeographicalScope = geographicalScope;
    149         mSerialNumber = serialNumber;
    150         mLocation = location;
    151         mServiceCategory = serviceCategory;
    152         mLanguage = language;
    153         mBody = body;
    154         mPriority = priority;
    155         mEtwsWarningInfo = etwsWarningInfo;
    156         mCmasWarningInfo = cmasWarningInfo;
    157     }
    158 
    159     /** Create a new SmsCbMessage object from a Parcel. */
    160     public SmsCbMessage(Parcel in) {
    161         mMessageFormat = in.readInt();
    162         mGeographicalScope = in.readInt();
    163         mSerialNumber = in.readInt();
    164         mLocation = new SmsCbLocation(in);
    165         mServiceCategory = in.readInt();
    166         mLanguage = in.readString();
    167         mBody = in.readString();
    168         mPriority = in.readInt();
    169         int type = in.readInt();
    170         switch (type) {
    171             case 'E':
    172                 // unparcel ETWS warning information
    173                 mEtwsWarningInfo = new SmsCbEtwsInfo(in);
    174                 mCmasWarningInfo = null;
    175                 break;
    176 
    177             case 'C':
    178                 // unparcel CMAS warning information
    179                 mEtwsWarningInfo = null;
    180                 mCmasWarningInfo = new SmsCbCmasInfo(in);
    181                 break;
    182 
    183             default:
    184                 mEtwsWarningInfo = null;
    185                 mCmasWarningInfo = null;
    186         }
    187     }
    188 
    189     /**
    190      * Flatten this object into a Parcel.
    191      *
    192      * @param dest  The Parcel in which the object should be written.
    193      * @param flags Additional flags about how the object should be written (ignored).
    194      */
    195     @Override
    196     public void writeToParcel(Parcel dest, int flags) {
    197         dest.writeInt(mMessageFormat);
    198         dest.writeInt(mGeographicalScope);
    199         dest.writeInt(mSerialNumber);
    200         mLocation.writeToParcel(dest, flags);
    201         dest.writeInt(mServiceCategory);
    202         dest.writeString(mLanguage);
    203         dest.writeString(mBody);
    204         dest.writeInt(mPriority);
    205         if (mEtwsWarningInfo != null) {
    206             // parcel ETWS warning information
    207             dest.writeInt('E');
    208             mEtwsWarningInfo.writeToParcel(dest, flags);
    209         } else if (mCmasWarningInfo != null) {
    210             // parcel CMAS warning information
    211             dest.writeInt('C');
    212             mCmasWarningInfo.writeToParcel(dest, flags);
    213         } else {
    214             // no ETWS or CMAS warning information
    215             dest.writeInt('0');
    216         }
    217     }
    218 
    219     public static final Parcelable.Creator<SmsCbMessage> CREATOR
    220             = new Parcelable.Creator<SmsCbMessage>() {
    221         @Override
    222         public SmsCbMessage createFromParcel(Parcel in) {
    223             return new SmsCbMessage(in);
    224         }
    225 
    226         @Override
    227         public SmsCbMessage[] newArray(int size) {
    228             return new SmsCbMessage[size];
    229         }
    230     };
    231 
    232     /**
    233      * Return the geographical scope of this message (GSM/UMTS only).
    234      *
    235      * @return Geographical scope
    236      */
    237     public int getGeographicalScope() {
    238         return mGeographicalScope;
    239     }
    240 
    241     /**
    242      * Return the broadcast serial number of broadcast (message identifier for CDMA, or
    243      * geographical scope + message code + update number for GSM/UMTS). The serial number plus
    244      * the location code uniquely identify a cell broadcast for duplicate detection.
    245      *
    246      * @return the 16-bit CDMA message identifier or GSM/UMTS serial number
    247      */
    248     public int getSerialNumber() {
    249         return mSerialNumber;
    250     }
    251 
    252     /**
    253      * Return the location identifier for this message, consisting of the MCC/MNC as a
    254      * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
    255      * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the
    256      * cell ID is also included. The {@link SmsCbLocation} object includes a method to test
    257      * if the location is included within another location area or within a PLMN and CellLocation.
    258      *
    259      * @return the geographical location code for duplicate message detection
    260      */
    261     public SmsCbLocation getLocation() {
    262         return mLocation;
    263     }
    264 
    265     /**
    266      * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation
    267      * of the category is radio technology specific. For ETWS and CMAS warnings, the information
    268      * provided by the category is available via {@link #getEtwsWarningInfo()} or
    269      * {@link #getCmasWarningInfo()} in a radio technology independent format.
    270      *
    271      * @return the radio technology specific service category
    272      */
    273     public int getServiceCategory() {
    274         return mServiceCategory;
    275     }
    276 
    277     /**
    278      * Get the ISO-639-1 language code for this message, or null if unspecified
    279      *
    280      * @return Language code
    281      */
    282     public String getLanguageCode() {
    283         return mLanguage;
    284     }
    285 
    286     /**
    287      * Get the body of this message, or null if no body available
    288      *
    289      * @return Body, or null
    290      */
    291     public String getMessageBody() {
    292         return mBody;
    293     }
    294 
    295     /**
    296      * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
    297      * @return an integer representing 3GPP or 3GPP2 message format
    298      */
    299     public int getMessageFormat() {
    300         return mMessageFormat;
    301     }
    302 
    303     /**
    304      * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL}
    305      * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return
    306      * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}.
    307      * @return an integer representing the message priority
    308      */
    309     public int getMessagePriority() {
    310         return mPriority;
    311     }
    312 
    313     /**
    314      * If this is an ETWS warning notification then this method will return an object containing
    315      * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an
    316      * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte
    317      * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the
    318      * ETWS primary notification timestamp and digital signature if received.
    319      *
    320      * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification
    321      */
    322     public SmsCbEtwsInfo getEtwsWarningInfo() {
    323         return mEtwsWarningInfo;
    324     }
    325 
    326     /**
    327      * If this is a CMAS warning notification then this method will return an object containing
    328      * the CMAS message class, category, response type, severity, urgency and certainty.
    329      * The message class is always present. Severity, urgency and certainty are present for CDMA
    330      * warning notifications containing a type 1 elements record and for GSM and UMTS warnings
    331      * except for the Presidential-level alert category. Category and response type are only
    332      * available for CDMA notifications containing a type 1 elements record.
    333      *
    334      * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification
    335      */
    336     public SmsCbCmasInfo getCmasWarningInfo() {
    337         return mCmasWarningInfo;
    338     }
    339 
    340     /**
    341      * Return whether this message is an emergency (PWS) message type.
    342      * @return true if the message is a public warning notification; false otherwise
    343      */
    344     public boolean isEmergencyMessage() {
    345         return mPriority == MESSAGE_PRIORITY_EMERGENCY;
    346     }
    347 
    348     /**
    349      * Return whether this message is an ETWS warning alert.
    350      * @return true if the message is an ETWS warning notification; false otherwise
    351      */
    352     public boolean isEtwsMessage() {
    353         return mEtwsWarningInfo != null;
    354     }
    355 
    356     /**
    357      * Return whether this message is a CMAS warning alert.
    358      * @return true if the message is a CMAS warning notification; false otherwise
    359      */
    360     public boolean isCmasMessage() {
    361         return mCmasWarningInfo != null;
    362     }
    363 
    364     @Override
    365     public String toString() {
    366         return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber="
    367                 + mSerialNumber + ", location=" + mLocation + ", serviceCategory="
    368                 + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
    369                 + ", priority=" + mPriority
    370                 + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
    371                 + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
    372     }
    373 
    374     /**
    375      * Describe the kinds of special objects contained in the marshalled representation.
    376      * @return a bitmask indicating this Parcelable contains no special objects
    377      */
    378     @Override
    379     public int describeContents() {
    380         return 0;
    381     }
    382 }
    383