diff options
| author | 2012-02-29 14:00:12 -0800 | |
|---|---|---|
| committer | 2012-02-29 14:00:12 -0800 | |
| commit | efba344b5a7b20e400daf5f41b2fbd688337f789 (patch) | |
| tree | 975a8df7a4810e39027535f68ecb814db3b5d59c /telephony/java/android | |
| parent | 0c49f03a0429b5c0c4a619256f7bca86a4997ae8 (diff) | |
Revert "Add support for CMAS warning notifications over CDMA." I'll submit again when the app change is ready.
This reverts commit 0c49f03a0429b5c0c4a619256f7bca86a4997ae8
Diffstat (limited to 'telephony/java/android')
| -rw-r--r-- | telephony/java/android/telephony/SmsCbCmasInfo.java | 308 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SmsCbConstants.java | 117 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SmsCbEtwsInfo.java | 206 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SmsCbLocation.java | 202 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SmsCbMessage.java | 603 | ||||
| -rw-r--r-- | telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java | 210 |
6 files changed, 457 insertions, 1189 deletions
diff --git a/telephony/java/android/telephony/SmsCbCmasInfo.java b/telephony/java/android/telephony/SmsCbCmasInfo.java deleted file mode 100644 index 7a89d94ab2ef..000000000000 --- a/telephony/java/android/telephony/SmsCbCmasInfo.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Contains CMAS warning notification Type 1 elements for a {@link SmsCbMessage}. - * Supported values for each element are defined in TIA-1149-0-1 (CMAS over CDMA) and - * 3GPP TS 23.041 (for GSM/UMTS). - * - * {@hide} - */ -public class SmsCbCmasInfo implements Parcelable { - - // CMAS message class (in GSM/UMTS message identifier or CDMA service category). - - /** Presidential-level alert (Korean Public Alert System Class 0 message). */ - public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00; - - /** Extreme threat to life and property (Korean Public Alert System Class 1 message). */ - public static final int CMAS_CLASS_EXTREME_THREAT = 0x01; - - /** Severe threat to life and property (Korean Public Alert System Class 1 message). */ - public static final int CMAS_CLASS_SEVERE_THREAT = 0x02; - - /** Child abduction emergency (AMBER Alert). */ - public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03; - - /** CMAS test message. */ - public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04; - - /** CMAS exercise. */ - public static final int CMAS_CLASS_CMAS_EXERCISE = 0x05; - - /** CMAS category for operator defined use. */ - public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06; - - /** CMAS category for warning types that are reserved for future extension. */ - public static final int CMAS_CLASS_UNKNOWN = -1; - - // CMAS alert category (in CDMA type 1 elements record). - - /** CMAS alert category: Geophysical including landslide. */ - public static final int CMAS_CATEGORY_GEO = 0x00; - - /** CMAS alert category: Meteorological including flood. */ - public static final int CMAS_CATEGORY_MET = 0x01; - - /** CMAS alert category: General emergency and public safety. */ - public static final int CMAS_CATEGORY_SAFETY = 0x02; - - /** CMAS alert category: Law enforcement, military, homeland/local/private security. */ - public static final int CMAS_CATEGORY_SECURITY = 0x03; - - /** CMAS alert category: Rescue and recovery. */ - public static final int CMAS_CATEGORY_RESCUE = 0x04; - - /** CMAS alert category: Fire suppression and rescue. */ - public static final int CMAS_CATEGORY_FIRE = 0x05; - - /** CMAS alert category: Medical and public health. */ - public static final int CMAS_CATEGORY_HEALTH = 0x06; - - /** CMAS alert category: Pollution and other environmental. */ - public static final int CMAS_CATEGORY_ENV = 0x07; - - /** CMAS alert category: Public and private transportation. */ - public static final int CMAS_CATEGORY_TRANSPORT = 0x08; - - /** CMAS alert category: Utility, telecom, other non-transport infrastructure. */ - public static final int CMAS_CATEGORY_INFRA = 0x09; - - /** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */ - public static final int CMAS_CATEGORY_CBRNE = 0x0a; - - /** CMAS alert category: Other events. */ - public static final int CMAS_CATEGORY_OTHER = 0x0b; - - /** - * CMAS alert category is unknown. The category is only available for CDMA broadcasts - * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown. - */ - public static final int CMAS_CATEGORY_UNKNOWN = -1; - - // CMAS response type (in CDMA type 1 elements record). - - /** CMAS response type: Take shelter in place. */ - public static final int CMAS_RESPONSE_TYPE_SHELTER = 0x00; - - /** CMAS response type: Evacuate (Relocate). */ - public static final int CMAS_RESPONSE_TYPE_EVACUATE = 0x01; - - /** CMAS response type: Make preparations. */ - public static final int CMAS_RESPONSE_TYPE_PREPARE = 0x02; - - /** CMAS response type: Execute a pre-planned activity. */ - public static final int CMAS_RESPONSE_TYPE_EXECUTE = 0x03; - - /** CMAS response type: Attend to information sources. */ - public static final int CMAS_RESPONSE_TYPE_MONITOR = 0x04; - - /** CMAS response type: Avoid hazard. */ - public static final int CMAS_RESPONSE_TYPE_AVOID = 0x05; - - /** CMAS response type: Evaluate the information in this message (not for public warnings). */ - public static final int CMAS_RESPONSE_TYPE_ASSESS = 0x06; - - /** CMAS response type: No action recommended. */ - public static final int CMAS_RESPONSE_TYPE_NONE = 0x07; - - /** - * CMAS response type is unknown. The response type is only available for CDMA broadcasts - * containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown. - */ - public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; - - // 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS severity type: Extraordinary threat to life or property. */ - public static final int CMAS_SEVERITY_EXTREME = 0x0; - - /** CMAS severity type: Significant threat to life or property. */ - public static final int CMAS_SEVERITY_SEVERE = 0x1; - - /** - * CMAS alert severity is unknown. The severity is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_SEVERITY_UNKNOWN = -1; - - // CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS urgency type: Responsive action should be taken immediately. */ - public static final int CMAS_URGENCY_IMMEDIATE = 0x0; - - /** CMAS urgency type: Responsive action should be taken within the next hour. */ - public static final int CMAS_URGENCY_EXPECTED = 0x1; - - /** - * CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_URGENCY_UNKNOWN = -1; - - // CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record). - - /** CMAS certainty type: Determined to have occurred or to be ongoing. */ - public static final int CMAS_CERTAINTY_OBSERVED = 0x0; - - /** CMAS certainty type: Likely (probability > ~50%). */ - public static final int CMAS_CERTAINTY_LIKELY = 0x1; - - /** - * CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts - * containing a type 1 elements record and for all GSM and UMTS alerts except for the - * Presidential-level alert class (Korean Public Alert System Class 0). - */ - public static final int CMAS_CERTAINTY_UNKNOWN = -1; - - /** CMAS message class. */ - private final int mMessageClass; - - /** CMAS category. */ - private final int mCategory; - - /** CMAS response type. */ - private final int mResponseType; - - /** CMAS severity. */ - private final int mSeverity; - - /** CMAS urgency. */ - private final int mUrgency; - - /** CMAS certainty. */ - private final int mCertainty; - - /** Create a new SmsCbCmasInfo object with the specified values. */ - public SmsCbCmasInfo(int messageClass, int category, int responseType, int severity, - int urgency, int certainty) { - mMessageClass = messageClass; - mCategory = category; - mResponseType = responseType; - mSeverity = severity; - mUrgency = urgency; - mCertainty = certainty; - } - - /** Create a new SmsCbCmasInfo object from a Parcel. */ - SmsCbCmasInfo(Parcel in) { - mMessageClass = in.readInt(); - mCategory = in.readInt(); - mResponseType = in.readInt(); - mSeverity = in.readInt(); - mUrgency = in.readInt(); - mCertainty = in.readInt(); - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mMessageClass); - dest.writeInt(mCategory); - dest.writeInt(mResponseType); - dest.writeInt(mSeverity); - dest.writeInt(mUrgency); - dest.writeInt(mCertainty); - } - - /** - * Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}. - * @return one of the {@code CMAS_CLASS} values - */ - public int getMessageClass() { - return mMessageClass; - } - - /** - * Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}. - * @return one of the {@code CMAS_CATEGORY} values - */ - public int getCategory() { - return mCategory; - } - - /** - * Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}. - * @return one of the {@code CMAS_RESPONSE_TYPE} values - */ - public int getResponseType() { - return mResponseType; - } - - /** - * Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}. - * @return one of the {@code CMAS_SEVERITY} values - */ - public int getSeverity() { - return mSeverity; - } - - /** - * Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}. - * @return one of the {@code CMAS_URGENCY} values - */ - public int getUrgency() { - return mUrgency; - } - - /** - * Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}. - * @return one of the {@code CMAS_CERTAINTY} values - */ - public int getCertainty() { - return mCertainty; - } - - @Override - public String toString() { - return "SmsCbCmasInfo{messageClass=" + mMessageClass + ", category=" + mCategory - + ", responseType=" + mResponseType + ", severity=" + mSeverity - + ", urgency=" + mUrgency + ", certainty=" + mCertainty + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } - - /** Creator for unparcelling objects. */ - public static final Parcelable.Creator<SmsCbCmasInfo> - CREATOR = new Parcelable.Creator<SmsCbCmasInfo>() { - public SmsCbCmasInfo createFromParcel(Parcel in) { - return new SmsCbCmasInfo(in); - } - - public SmsCbCmasInfo[] newArray(int size) { - return new SmsCbCmasInfo[size]; - } - }; -} diff --git a/telephony/java/android/telephony/SmsCbConstants.java b/telephony/java/android/telephony/SmsCbConstants.java new file mode 100644 index 000000000000..a1b4adf19baf --- /dev/null +++ b/telephony/java/android/telephony/SmsCbConstants.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +/** + * Constants used in SMS Cell Broadcast messages. + * + * {@hide} + */ +public interface SmsCbConstants { + /** Start of PWS Message Identifier range (includes ETWS and CMAS). */ + public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER = 0x1100; + + /** Bitmask for messages of ETWS type (including future extensions). */ + public static final int MESSAGE_ID_ETWS_TYPE_MASK = 0xFFF8; + + /** Value for messages of ETWS type after applying {@link #MESSAGE_ID_ETWS_TYPE_MASK}. */ + public static final int MESSAGE_ID_ETWS_TYPE = 0x1100; + + /** ETWS Message Identifier for earthquake warning message. */ + public static final int MESSAGE_ID_ETWS_EARTHQUAKE_WARNING = 0x1100; + + /** ETWS Message Identifier for tsunami warning message. */ + public static final int MESSAGE_ID_ETWS_TSUNAMI_WARNING = 0x1101; + + /** ETWS Message Identifier for earthquake and tsunami combined warning message. */ + public static final int MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING = 0x1102; + + /** ETWS Message Identifier for test message. */ + public static final int MESSAGE_ID_ETWS_TEST_MESSAGE = 0x1103; + + /** ETWS Message Identifier for messages related to other emergency types. */ + public static final int MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE = 0x1104; + + /** Start of CMAS Message Identifier range. */ + public static final int MESSAGE_ID_CMAS_FIRST_IDENTIFIER = 0x1112; + + /** CMAS Message Identifier for Presidential Level alerts. */ + public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL = 0x1112; + + /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed. */ + public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED = 0x1113; + + /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely. */ + public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY = 0x1114; + + /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed. */ + public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED = 0x1115; + + /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely. */ + public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY = 0x1116; + + /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed. */ + public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED = 0x1117; + + /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely. */ + public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY = 0x1118; + + /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed. */ + public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED = 0x1119; + + /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely. */ + public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY = 0x111A; + + /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert). */ + public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY = 0x111B; + + /** CMAS Message Identifier for the Required Monthly Test. */ + public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST = 0x111C; + + /** CMAS Message Identifier for CMAS Exercise. */ + public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE = 0x111D; + + /** CMAS Message Identifier for operator defined use. */ + public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE = 0x111E; + + /** End of CMAS Message Identifier range (including future extensions). */ + public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = 0x112F; + + /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */ + public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER = 0x18FF; + + /** ETWS message code flag to activate the popup display. */ + public static final int MESSAGE_CODE_ETWS_ACTIVATE_POPUP = 0x100; + + /** ETWS message code flag to activate the emergency user alert. */ + public static final int MESSAGE_CODE_ETWS_EMERGENCY_USER_ALERT = 0x200; + + /** ETWS warning type value for earthquake. */ + public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; + + /** ETWS warning type value for tsunami. */ + public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; + + /** ETWS warning type value for earthquake and tsunami. */ + public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; + + /** ETWS warning type value for test broadcast. */ + public static final int ETWS_WARNING_TYPE_TEST = 0x03; + + /** ETWS warning type value for other notifications. */ + public static final int ETWS_WARNING_TYPE_OTHER = 0x04; +} diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java deleted file mode 100644 index 0890d528f866..000000000000 --- a/telephony/java/android/telephony/SmsCbEtwsInfo.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.os.Parcel; -import android.os.Parcelable; -import android.text.format.Time; - -import com.android.internal.telephony.IccUtils; - -import java.util.Arrays; - -/** - * Contains information elements for a GSM or UMTS ETWS warning notification. - * Supported values for each element are defined in 3GPP TS 23.041. - * - * {@hide} - */ -public class SmsCbEtwsInfo implements Parcelable { - - /** ETWS warning type for earthquake. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; - - /** ETWS warning type for tsunami. */ - public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; - - /** ETWS warning type for earthquake and tsunami. */ - public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; - - /** ETWS warning type for test messages. */ - public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03; - - /** ETWS warning type for other emergency types. */ - public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04; - - /** Unknown ETWS warning type. */ - public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; - - /** One of the ETWS warning type constants defined in this class. */ - private final int mWarningType; - - /** Whether or not to activate the emergency user alert tone and vibration. */ - private final boolean mEmergencyUserAlert; - - /** Whether or not to activate a popup alert. */ - private final boolean mActivatePopup; - - /** - * 50-byte security information (ETWS primary notification for GSM only). As of Release 10, - * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp - * and digital signature if received. Therefore it is treated as a raw byte array and - * parceled with the broadcast intent if present, but the timestamp is only computed if an - * application asks for the individual components. - */ - private final byte[] mWarningSecurityInformation; - - /** Create a new SmsCbEtwsInfo object with the specified values. */ - public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup, - byte[] warningSecurityInformation) { - mWarningType = warningType; - mEmergencyUserAlert = emergencyUserAlert; - mActivatePopup = activatePopup; - mWarningSecurityInformation = warningSecurityInformation; - } - - /** Create a new SmsCbEtwsInfo object from a Parcel. */ - SmsCbEtwsInfo(Parcel in) { - mWarningType = in.readInt(); - mEmergencyUserAlert = (in.readInt() != 0); - mActivatePopup = (in.readInt() != 0); - mWarningSecurityInformation = in.createByteArray(); - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mWarningType); - dest.writeInt(mEmergencyUserAlert ? 1 : 0); - dest.writeInt(mActivatePopup ? 1 : 0); - dest.writeByteArray(mWarningSecurityInformation); - } - - /** - * Returns the ETWS warning type. - * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE} - */ - public int getWarningType() { - return mWarningType; - } - - /** - * Returns the ETWS emergency user alert flag. - * @return true to notify terminal to activate emergency user alert; false otherwise - */ - public boolean isEmergencyUserAlert() { - return mEmergencyUserAlert; - } - - /** - * Returns the ETWS activate popup flag. - * @return true to notify terminal to activate display popup; false otherwise - */ - public boolean isPopupAlert() { - return mActivatePopup; - } - - /** - * Returns the Warning-Security-Information timestamp (GSM primary notifications only). - * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. - * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present - */ - public long getPrimaryNotificationTimestamp() { - if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { - return 0; - } - - int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]); - int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]); - int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]); - int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]); - int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]); - int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]); - - // For the timezone, the most significant bit of the - // least significant nibble is the sign byte - // (meaning the max range of this field is 79 quarter-hours, - // which is more than enough) - - byte tzByte = mWarningSecurityInformation[6]; - - // Mask out sign bit. - int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); - - timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; - - Time time = new Time(Time.TIMEZONE_UTC); - - // We only need to support years above 2000. - time.year = year + 2000; - time.month = month - 1; - time.monthDay = day; - time.hour = hour; - time.minute = minute; - time.second = second; - - // Timezone offset is in quarter hours. - return time.toMillis(true) - (long) (timezoneOffset * 15 * 60 * 1000); - } - - /** - * Returns the digital signature (GSM primary notifications only). As of Release 10, - * 3GPP TS 23.041 states that the UE shall ignore this value if received. - * @return a byte array containing a copy of the primary notification digital signature - */ - public byte[] getPrimaryNotificationSignature() { - if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) { - return null; - } - return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50); - } - - @Override - public String toString() { - return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert=" - + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } - - /** Creator for unparcelling objects. */ - public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() { - public SmsCbEtwsInfo createFromParcel(Parcel in) { - return new SmsCbEtwsInfo(in); - } - - public SmsCbEtwsInfo[] newArray(int size) { - return new SmsCbEtwsInfo[size]; - } - }; -} diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java deleted file mode 100644 index 7b5bd0d4bb71..000000000000 --- a/telephony/java/android/telephony/SmsCbLocation.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.telephony.gsm.GsmCellLocation; - -/** - * Represents the location and geographical scope of a cell broadcast message. - * For GSM/UMTS, the Location Area and Cell ID are set when the broadcast - * geographical scope is cell wide or Location Area wide. For CDMA, the - * broadcast geographical scope is always PLMN wide. - * - * @hide - */ -public class SmsCbLocation implements Parcelable { - - /** The PLMN. Note that this field may be an empty string, but isn't allowed to be null. */ - private final String mPlmn; - - private final int mLac; - private final int mCid; - - /** - * Construct an empty location object. This is used for some test cases, and for - * cell broadcasts saved in older versions of the database without location info. - */ - public SmsCbLocation() { - mPlmn = ""; - mLac = -1; - mCid = -1; - } - - /** - * Construct a location object for the PLMN. This class is immutable, so - * the same object can be reused for multiple broadcasts. - */ - public SmsCbLocation(String plmn) { - mPlmn = plmn; - mLac = -1; - mCid = -1; - } - - /** - * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so - * the same object can be reused for multiple broadcasts. - */ - public SmsCbLocation(String plmn, int lac, int cid) { - mPlmn = plmn; - mLac = lac; - mCid = cid; - } - - /** - * Initialize the object from a Parcel. - */ - public SmsCbLocation(Parcel in) { - mPlmn = in.readString(); - mLac = in.readInt(); - mCid = in.readInt(); - } - - /** - * Returns the MCC/MNC of the network as a String. - * @return the PLMN identifier (MCC+MNC) as a String - */ - public String getPlmn() { - return mPlmn; - } - - /** - * Returns the GSM location area code, or UMTS service area code. - * @return location area code, -1 if unknown, 0xffff max legal value - */ - public int getLac() { - return mLac; - } - - /** - * Returns the GSM or UMTS cell ID. - * @return gsm cell id, -1 if unknown, 0xffff max legal value - */ - public int getCid() { - return mCid; - } - - @Override - public int hashCode() { - int hash = mPlmn.hashCode(); - hash = hash * 31 + mLac; - hash = hash * 31 + mCid; - return hash; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o == null || !(o instanceof SmsCbLocation)) { - return false; - } - SmsCbLocation other = (SmsCbLocation) o; - return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid; - } - - @Override - public String toString() { - return '[' + mPlmn + ',' + mLac + ',' + mCid + ']'; - } - - /** - * Test whether this location is within the location area of the specified object. - * - * @param area the location area to compare with this location - * @return true if this location is contained within the specified location area - */ - public boolean isInLocationArea(SmsCbLocation area) { - if (mCid != -1 && mCid != area.mCid) { - return false; - } - if (mLac != -1 && mLac != area.mLac) { - return false; - } - return mPlmn.equals(area.mPlmn); - } - - /** - * Test whether this location is within the location area of the CellLocation. - * - * @param plmn the PLMN to use for comparison - * @param lac the Location Area (GSM) or Service Area (UMTS) to compare with - * @param cid the Cell ID to compare with - * @return true if this location is contained within the specified PLMN, LAC, and Cell ID - */ - public boolean isInLocationArea(String plmn, int lac, int cid) { - if (!mPlmn.equals(plmn)) { - return false; - } - - if (mLac != -1 && mLac != lac) { - return false; - } - - if (mCid != -1 && mCid != cid) { - return false; - } - - return true; - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mPlmn); - dest.writeInt(mLac); - dest.writeInt(mCid); - } - - public static final Parcelable.Creator<SmsCbLocation> CREATOR - = new Parcelable.Creator<SmsCbLocation>() { - @Override - public SmsCbLocation createFromParcel(Parcel in) { - return new SmsCbLocation(in); - } - - @Override - public SmsCbLocation[] newArray(int size) { - return new SmsCbLocation[size]; - } - }; - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } -} diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java index 046bf8c700eb..383e0f9c90c4 100644 --- a/telephony/java/android/telephony/SmsCbMessage.java +++ b/telephony/java/android/telephony/SmsCbMessage.java @@ -16,367 +16,444 @@ package android.telephony; -import android.os.Parcel; -import android.os.Parcelable; +import android.text.format.Time; +import android.util.Log; + +import com.android.internal.telephony.GsmAlphabet; +import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.gsm.SmsCbHeader; + +import java.io.UnsupportedEncodingException; /** - * Parcelable object containing a received cell broadcast message. There are four different types - * of Cell Broadcast messages: - * - * <ul> - * <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li> - * <li>cell information messages, broadcast on channel 50, indicating the current cell name for - * roaming purposes (required to display on the idle screen in Brazil)</li> - * <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li> - * <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li> - * </ul> - * - * <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only), - * UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were - * unified under a common name, avoiding some names, such as "Message Identifier", that refer to - * two completely different concepts in 3GPP and CDMA. - * - * <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name - * of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP - * and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the - * application should - * - * <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used - * to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is - * unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit - * Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number - * are considered unique to the PLMN, to the current cell, or to the current Location Area (or - * Service Area in UMTS). The relevant values are concatenated into a single String which will be - * unique if the messages are not duplicates. - * - * <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the - * pages of a GSM multi-page cell broadcast into a single SmsCbMessage object. - * - * <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive - * {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts. - * Only system applications such as the CellBroadcastReceiver may receive notifications for - * emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or - * interference with the immediate display of the alert message and playing of the alert sound and - * vibration pattern, which could be caused by poorly written or malicious non-system code. + * Describes an SMS-CB message. * - * @hide + * {@hide} */ -public class SmsCbMessage implements Parcelable { +public class SmsCbMessage { - protected static final String LOG_TAG = "SMSCB"; - - /** Cell wide geographical scope with immediate display (GSM/UMTS only). */ + /** + * Cell wide immediate geographical scope + */ public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; - /** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */ + /** + * PLMN wide geographical scope + */ public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; - /** Location / service area wide geographical scope (GSM/UMTS only). */ + /** + * Location / service area wide geographical scope + */ public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2; - /** Cell wide geographical scope (GSM/UMTS only). */ + /** + * Cell wide geographical scope + */ public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; - /** GSM or UMTS format cell broadcast. */ - public static final int MESSAGE_FORMAT_3GPP = 1; - - /** CDMA format cell broadcast. */ - public static final int MESSAGE_FORMAT_3GPP2 = 2; - - /** Normal message priority. */ - public static final int MESSAGE_PRIORITY_NORMAL = 0; - - /** Interactive message priority. */ - public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; - - /** Urgent message priority. */ - public static final int MESSAGE_PRIORITY_URGENT = 2; - - /** Emergency message priority. */ - public static final int MESSAGE_PRIORITY_EMERGENCY = 3; - - /** Format of this message (for interpretation of service category values). */ - private final int mMessageFormat; - - /** Geographical scope of broadcast. */ - private final int mGeographicalScope; - /** - * Serial number of broadcast (message identifier for CDMA, geographical scope + message code + - * update number for GSM/UMTS). The serial number plus the location code uniquely identify - * a cell broadcast for duplicate detection. + * Create an instance of this class from a received PDU + * + * @param pdu PDU bytes + * @return An instance of this class, or null if invalid pdu */ - private final int mSerialNumber; + public static SmsCbMessage createFromPdu(byte[] pdu) { + try { + return new SmsCbMessage(pdu); + } catch (IllegalArgumentException e) { + Log.w(LOG_TAG, "Failed parsing SMS-CB pdu", e); + return null; + } + } + + private static final String LOG_TAG = "SMSCB"; /** - * Location identifier for this message. It consists of the current operator MCC/MNC as a - * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the - * message is not binary 01, the Location Area is included for comparison. If the GS is - * 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified. + * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5. */ - private final SmsCbLocation mLocation; + private static final String[] LANGUAGE_CODES_GROUP_0 = { + "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu", + "pl", null + }; /** - * 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings, - * the information provided by the category is also available via {@link #getEtwsWarningInfo()} - * or {@link #getCmasWarningInfo()}. + * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5. */ - private final int mServiceCategory; - - /** Message language, as a two-character string, e.g. "en". */ - private final String mLanguage; + private static final String[] LANGUAGE_CODES_GROUP_2 = { + "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null, + null, null + }; - /** Message body, as a String. */ - private final String mBody; + private static final char CARRIAGE_RETURN = 0x0d; - /** Message priority (including emergency priority). */ - private final int mPriority; + private static final int PDU_BODY_PAGE_LENGTH = 82; - /** ETWS warning notification information (ETWS warnings only). */ - private final SmsCbEtwsInfo mEtwsWarningInfo; + private SmsCbHeader mHeader; - /** CMAS warning notification information (CMAS warnings only). */ - private final SmsCbCmasInfo mCmasWarningInfo; + private String mLanguage; - /** - * Create a new SmsCbMessage with the specified data. - */ - public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, - SmsCbLocation location, int serviceCategory, String language, String body, - int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) { - mMessageFormat = messageFormat; - mGeographicalScope = geographicalScope; - mSerialNumber = serialNumber; - mLocation = location; - mServiceCategory = serviceCategory; - mLanguage = language; - mBody = body; - mPriority = priority; - mEtwsWarningInfo = etwsWarningInfo; - mCmasWarningInfo = cmasWarningInfo; - } + private String mBody; - /** Create a new SmsCbMessage object from a Parcel. */ - public SmsCbMessage(Parcel in) { - mMessageFormat = in.readInt(); - mGeographicalScope = in.readInt(); - mSerialNumber = in.readInt(); - mLocation = new SmsCbLocation(in); - mServiceCategory = in.readInt(); - mLanguage = in.readString(); - mBody = in.readString(); - mPriority = in.readInt(); - int type = in.readInt(); - switch (type) { - case 'E': - // unparcel ETWS warning information - mEtwsWarningInfo = new SmsCbEtwsInfo(in); - mCmasWarningInfo = null; - break; + /** Timestamp of ETWS primary notification with security. */ + private long mPrimaryNotificationTimestamp; - case 'C': - // unparcel CMAS warning information - mEtwsWarningInfo = null; - mCmasWarningInfo = new SmsCbCmasInfo(in); - break; + /** 43 byte digital signature of ETWS primary notification with security. */ + private byte[] mPrimaryNotificationDigitalSignature; - default: - mEtwsWarningInfo = null; - mCmasWarningInfo = null; - } - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mMessageFormat); - dest.writeInt(mGeographicalScope); - dest.writeInt(mSerialNumber); - mLocation.writeToParcel(dest, flags); - dest.writeInt(mServiceCategory); - dest.writeString(mLanguage); - dest.writeString(mBody); - dest.writeInt(mPriority); - if (mEtwsWarningInfo != null) { - // parcel ETWS warning information - dest.writeInt('E'); - mEtwsWarningInfo.writeToParcel(dest, flags); - } else if (mCmasWarningInfo != null) { - // parcel CMAS warning information - dest.writeInt('C'); - mCmasWarningInfo.writeToParcel(dest, flags); + private SmsCbMessage(byte[] pdu) throws IllegalArgumentException { + mHeader = new SmsCbHeader(pdu); + if (mHeader.format == SmsCbHeader.FORMAT_ETWS_PRIMARY) { + mBody = "ETWS"; + // ETWS primary notification with security is 56 octets in length + if (pdu.length >= SmsCbHeader.PDU_LENGTH_ETWS) { + mPrimaryNotificationTimestamp = getTimestampMillis(pdu); + mPrimaryNotificationDigitalSignature = new byte[43]; + // digital signature starts after 6 byte header and 7 byte timestamp + System.arraycopy(pdu, 13, mPrimaryNotificationDigitalSignature, 0, 43); + } } else { - // no ETWS or CMAS warning information - dest.writeInt('0'); + parseBody(pdu); } } - public static final Parcelable.Creator<SmsCbMessage> CREATOR - = new Parcelable.Creator<SmsCbMessage>() { - @Override - public SmsCbMessage createFromParcel(Parcel in) { - return new SmsCbMessage(in); - } - - @Override - public SmsCbMessage[] newArray(int size) { - return new SmsCbMessage[size]; - } - }; - /** - * Return the geographical scope of this message (GSM/UMTS only). + * Return the geographical scope of this message, one of + * {@link #GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE}, + * {@link #GEOGRAPHICAL_SCOPE_PLMN_WIDE}, + * {@link #GEOGRAPHICAL_SCOPE_LA_WIDE}, + * {@link #GEOGRAPHICAL_SCOPE_CELL_WIDE} * * @return Geographical scope */ public int getGeographicalScope() { - return mGeographicalScope; + return mHeader.geographicalScope; } /** - * Return the broadcast serial number of broadcast (message identifier for CDMA, or - * geographical scope + message code + update number for GSM/UMTS). The serial number plus - * the location code uniquely identify a cell broadcast for duplicate detection. + * Get the ISO-639-1 language code for this message, or null if unspecified * - * @return the 16-bit CDMA message identifier or GSM/UMTS serial number + * @return Language code */ - public int getSerialNumber() { - return mSerialNumber; + public String getLanguageCode() { + return mLanguage; } /** - * Return the location identifier for this message, consisting of the MCC/MNC as a - * 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the - * message is not binary 01, the Location Area is included. If the GS is 00 or 11, the - * cell ID is also included. The {@link SmsCbLocation} object includes a method to test - * if the location is included within another location area or within a PLMN and CellLocation. + * Get the body of this message, or null if no body available * - * @return the geographical location code for duplicate message detection + * @return Body, or null */ - public SmsCbLocation getLocation() { - return mLocation; + public String getMessageBody() { + return mBody; } /** - * Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation - * of the category is radio technology specific. For ETWS and CMAS warnings, the information - * provided by the category is available via {@link #getEtwsWarningInfo()} or - * {@link #getCmasWarningInfo()} in a radio technology independent format. + * Get the message identifier of this message (0-65535) * - * @return the radio technology specific service category + * @return Message identifier */ - public int getServiceCategory() { - return mServiceCategory; + public int getMessageIdentifier() { + return mHeader.messageIdentifier; } /** - * Get the ISO-639-1 language code for this message, or null if unspecified + * Get the message code of this message (0-1023) * - * @return Language code + * @return Message code */ - public String getLanguageCode() { - return mLanguage; + public int getMessageCode() { + return mHeader.messageCode; } /** - * Get the body of this message, or null if no body available + * Get the update number of this message (0-15) * - * @return Body, or null + * @return Update number */ - public String getMessageBody() { - return mBody; + public int getUpdateNumber() { + return mHeader.updateNumber; } /** - * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}). - * @return an integer representing 3GPP or 3GPP2 message format + * Get the format of this message. + * @return {@link SmsCbHeader#FORMAT_GSM}, {@link SmsCbHeader#FORMAT_UMTS}, or + * {@link SmsCbHeader#FORMAT_ETWS_PRIMARY} */ public int getMessageFormat() { - return mMessageFormat; + return mHeader.format; } /** - * Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL} - * and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return - * {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}. - * @return an integer representing the message priority + * For ETWS primary notifications, return the emergency user alert flag. + * @return true to notify terminal to activate emergency user alert; false otherwise */ - public int getMessagePriority() { - return mPriority; + public boolean getEtwsEmergencyUserAlert() { + return mHeader.etwsEmergencyUserAlert; } /** - * If this is an ETWS warning notification then this method will return an object containing - * the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an - * ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte - * digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the - * ETWS primary notification timestamp and digital signature if received. - * - * @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification + * For ETWS primary notifications, return the popup flag. + * @return true to notify terminal to activate display popup; false otherwise */ - public SmsCbEtwsInfo getEtwsWarningInfo() { - return mEtwsWarningInfo; + public boolean getEtwsPopup() { + return mHeader.etwsPopup; } /** - * If this is a CMAS warning notification then this method will return an object containing - * the CMAS message class, category, response type, severity, urgency and certainty. - * The message class is always present. Severity, urgency and certainty are present for CDMA - * warning notifications containing a type 1 elements record and for GSM and UMTS warnings - * except for the Presidential-level alert category. Category and response type are only - * available for CDMA notifications containing a type 1 elements record. - * - * @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification + * For ETWS primary notifications, return the warning type. + * @return a value such as {@link SmsCbConstants#ETWS_WARNING_TYPE_EARTHQUAKE} */ - public SmsCbCmasInfo getCmasWarningInfo() { - return mCmasWarningInfo; + public int getEtwsWarningType() { + return mHeader.etwsWarningType; } /** - * Return whether this message is an emergency (PWS) message type. - * @return true if the message is a public warning notification; false otherwise + * For ETWS primary notifications, return the Warning-Security-Information timestamp. + * @return a timestamp in System.currentTimeMillis() format. */ - public boolean isEmergencyMessage() { - return mPriority == MESSAGE_PRIORITY_EMERGENCY; + public long getEtwsSecurityTimestamp() { + return mPrimaryNotificationTimestamp; } /** - * Return whether this message is an ETWS warning alert. - * @return true if the message is an ETWS warning notification; false otherwise + * For ETWS primary notifications, return the 43 byte digital signature. + * @return a byte array containing a copy of the digital signature */ - public boolean isEtwsMessage() { - return mEtwsWarningInfo != null; + public byte[] getEtwsSecuritySignature() { + return mPrimaryNotificationDigitalSignature.clone(); } /** - * Return whether this message is a CMAS warning alert. - * @return true if the message is a CMAS warning notification; false otherwise + * Parse and unpack the body text according to the encoding in the DCS. + * After completing successfully this method will have assigned the body + * text into mBody, and optionally the language code into mLanguage + * + * @param pdu The pdu */ - public boolean isCmasMessage() { - return mCmasWarningInfo != null; + private void parseBody(byte[] pdu) { + int encoding; + boolean hasLanguageIndicator = false; + + // Extract encoding and language from DCS, as defined in 3gpp TS 23.038, + // section 5. + switch ((mHeader.dataCodingScheme & 0xf0) >> 4) { + case 0x00: + encoding = SmsMessage.ENCODING_7BIT; + mLanguage = LANGUAGE_CODES_GROUP_0[mHeader.dataCodingScheme & 0x0f]; + break; + + case 0x01: + hasLanguageIndicator = true; + if ((mHeader.dataCodingScheme & 0x0f) == 0x01) { + encoding = SmsMessage.ENCODING_16BIT; + } else { + encoding = SmsMessage.ENCODING_7BIT; + } + break; + + case 0x02: + encoding = SmsMessage.ENCODING_7BIT; + mLanguage = LANGUAGE_CODES_GROUP_2[mHeader.dataCodingScheme & 0x0f]; + break; + + case 0x03: + encoding = SmsMessage.ENCODING_7BIT; + break; + + case 0x04: + case 0x05: + switch ((mHeader.dataCodingScheme & 0x0c) >> 2) { + case 0x01: + encoding = SmsMessage.ENCODING_8BIT; + break; + + case 0x02: + encoding = SmsMessage.ENCODING_16BIT; + break; + + case 0x00: + default: + encoding = SmsMessage.ENCODING_7BIT; + break; + } + break; + + case 0x06: + case 0x07: + // Compression not supported + case 0x09: + // UDH structure not supported + case 0x0e: + // Defined by the WAP forum not supported + encoding = SmsMessage.ENCODING_UNKNOWN; + break; + + case 0x0f: + if (((mHeader.dataCodingScheme & 0x04) >> 2) == 0x01) { + encoding = SmsMessage.ENCODING_8BIT; + } else { + encoding = SmsMessage.ENCODING_7BIT; + } + break; + + default: + // Reserved values are to be treated as 7-bit + encoding = SmsMessage.ENCODING_7BIT; + break; + } + + if (mHeader.format == SmsCbHeader.FORMAT_UMTS) { + // Payload may contain multiple pages + int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH]; + + if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) + * nrPages) { + throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match " + + nrPages + " pages"); + } + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < nrPages; i++) { + // Each page is 82 bytes followed by a length octet indicating + // the number of useful octets within those 82 + int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i; + int length = pdu[offset + PDU_BODY_PAGE_LENGTH]; + + if (length > PDU_BODY_PAGE_LENGTH) { + throw new IllegalArgumentException("Page length " + length + + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH); + } + + sb.append(unpackBody(pdu, encoding, offset, length, hasLanguageIndicator)); + } + mBody = sb.toString(); + } else { + // Payload is one single page + int offset = SmsCbHeader.PDU_HEADER_LENGTH; + int length = pdu.length - offset; + + mBody = unpackBody(pdu, encoding, offset, length, hasLanguageIndicator); + } } - @Override - public String toString() { - return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber=" - + mSerialNumber + ", location=" + mLocation + ", serviceCategory=" - + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody - + ", priority=" + mPriority - + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "") - + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}'; + /** + * Unpack body text from the pdu using the given encoding, position and + * length within the pdu + * + * @param pdu The pdu + * @param encoding The encoding, as derived from the DCS + * @param offset Position of the first byte to unpack + * @param length Number of bytes to unpack + * @param hasLanguageIndicator true if the body text is preceded by a + * language indicator. If so, this method will as a side-effect + * assign the extracted language code into mLanguage + * @return Body text + */ + private String unpackBody(byte[] pdu, int encoding, int offset, int length, + boolean hasLanguageIndicator) { + String body = null; + + switch (encoding) { + case SmsMessage.ENCODING_7BIT: + body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7); + + if (hasLanguageIndicator && body != null && body.length() > 2) { + // Language is two GSM characters followed by a CR. + // The actual body text is offset by 3 characters. + mLanguage = body.substring(0, 2); + body = body.substring(3); + } + break; + + case SmsMessage.ENCODING_16BIT: + if (hasLanguageIndicator && pdu.length >= offset + 2) { + // Language is two GSM characters. + // The actual body text is offset by 2 bytes. + mLanguage = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2); + offset += 2; + length -= 2; + } + + try { + body = new String(pdu, offset, (length & 0xfffe), "utf-16"); + } catch (UnsupportedEncodingException e) { + // Eeeek + } + break; + + default: + break; + } + + if (body != null) { + // Remove trailing carriage return + for (int i = body.length() - 1; i >= 0; i--) { + if (body.charAt(i) != CARRIAGE_RETURN) { + body = body.substring(0, i + 1); + break; + } + } + } else { + body = ""; + } + + return body; } /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects + * Parses an ETWS primary notification timestamp and returns a currentTimeMillis()-style + * timestamp. Copied from com.android.internal.telephony.gsm.SmsMessage. + * @param pdu the ETWS primary notification PDU to decode + * @return the UTC timestamp from the Warning-Security-Information parameter */ + private long getTimestampMillis(byte[] pdu) { + // Timestamp starts after CB header, in pdu[6] + int year = IccUtils.gsmBcdByteToInt(pdu[6]); + int month = IccUtils.gsmBcdByteToInt(pdu[7]); + int day = IccUtils.gsmBcdByteToInt(pdu[8]); + int hour = IccUtils.gsmBcdByteToInt(pdu[9]); + int minute = IccUtils.gsmBcdByteToInt(pdu[10]); + int second = IccUtils.gsmBcdByteToInt(pdu[11]); + + // For the timezone, the most significant bit of the + // least significant nibble is the sign byte + // (meaning the max range of this field is 79 quarter-hours, + // which is more than enough) + + byte tzByte = pdu[12]; + + // Mask out sign bit. + int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); + + timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; + + Time time = new Time(Time.TIMEZONE_UTC); + + // It's 2006. Should I really support years < 2000? + time.year = year >= 90 ? year + 1900 : year + 2000; + time.month = month - 1; + time.monthDay = day; + time.hour = hour; + time.minute = minute; + time.second = second; + + // Timezone offset is in quarter hours. + return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000); + } + + /** + * Append text to the message body. This is used to concatenate multi-page GSM broadcasts. + * @param body the text to append to this message + */ + public void appendToBody(String body) { + mBody = mBody + body; + } + @Override - public int describeContents() { - return 0; + public String toString() { + return "SmsCbMessage{" + mHeader.toString() + ", language=" + mLanguage + + ", body=\"" + mBody + "\"}"; } } diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java deleted file mode 100644 index f94efd8f56d7..000000000000 --- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony.cdma; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * CDMA Service Category Program Data from SCPT teleservice SMS. - * The CellBroadcastReceiver app receives an Intent with action - * {@link android.provider.Telephony.Sms.Intents#SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION} - * containing an array of these objects to update its list of cell broadcast service categories - * to display. - * - * {@hide} - */ -public class CdmaSmsCbProgramData implements Parcelable { - - /** Delete the specified service category from the list of enabled categories. */ - public static final int OPERATION_DELETE_CATEGORY = 0; - - /** Add the specified service category to the list of enabled categories. */ - public static final int OPERATION_ADD_CATEGORY = 1; - - /** Clear all service categories from the list of enabled categories. */ - public static final int OPERATION_CLEAR_CATEGORIES = 2; - - /** Alert option: no alert. */ - public static final int ALERT_OPTION_NO_ALERT = 0; - - /** Alert option: default alert. */ - public static final int ALERT_OPTION_DEFAULT_ALERT = 1; - - /** Alert option: vibrate alert once. */ - public static final int ALERT_OPTION_VIBRATE_ONCE = 2; - - /** Alert option: vibrate alert - repeat. */ - public static final int ALERT_OPTION_VIBRATE_REPEAT = 3; - - /** Alert option: visual alert once. */ - public static final int ALERT_OPTION_VISUAL_ONCE = 4; - - /** Alert option: visual alert - repeat. */ - public static final int ALERT_OPTION_VISUAL_REPEAT = 5; - - /** Alert option: low-priority alert once. */ - public static final int ALERT_OPTION_LOW_PRIORITY_ONCE = 6; - - /** Alert option: low-priority alert - repeat. */ - public static final int ALERT_OPTION_LOW_PRIORITY_REPEAT = 7; - - /** Alert option: medium-priority alert once. */ - public static final int ALERT_OPTION_MED_PRIORITY_ONCE = 8; - - /** Alert option: medium-priority alert - repeat. */ - public static final int ALERT_OPTION_MED_PRIORITY_REPEAT = 9; - - /** Alert option: high-priority alert once. */ - public static final int ALERT_OPTION_HIGH_PRIORITY_ONCE = 10; - - /** Alert option: high-priority alert - repeat. */ - public static final int ALERT_OPTION_HIGH_PRIORITY_REPEAT = 11; - - /** Service category operation (add/delete/clear). */ - private final int mOperation; - - /** Service category to modify. */ - private final int mCategory; - - /** Language used for service category name (ISO 639 two character code). */ - private final String mLanguage; - - /** Maximum number of messages to store for this service category. */ - private final int mMaxMessages; - - /** Service category alert option. */ - private final int mAlertOption; - - /** Name of service category. */ - private final String mCategoryName; - - /** Create a new CdmaSmsCbProgramData object with the specified values. */ - public CdmaSmsCbProgramData(int operation, int category, String language, int maxMessages, - int alertOption, String categoryName) { - mOperation = operation; - mCategory = category; - mLanguage = language; - mMaxMessages = maxMessages; - mAlertOption = alertOption; - mCategoryName = categoryName; - } - - /** Create a new CdmaSmsCbProgramData object from a Parcel. */ - CdmaSmsCbProgramData(Parcel in) { - mOperation = in.readInt(); - mCategory = in.readInt(); - mLanguage = in.readString(); - mMaxMessages = in.readInt(); - mAlertOption = in.readInt(); - mCategoryName = in.readString(); - } - - /** - * Flatten this object into a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written (ignored). - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mOperation); - dest.writeInt(mCategory); - dest.writeString(mLanguage); - dest.writeInt(mMaxMessages); - dest.writeInt(mAlertOption); - dest.writeString(mCategoryName); - } - - /** - * Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}. - * @return one of the {@code OPERATION_*} values - */ - public int getOperation() { - return mOperation; - } - - /** - * Returns the CDMA service category to modify. - * @return a 16-bit CDMA service category value - */ - public int getCategory() { - return mCategory; - } - - /** - * Returns the ISO-639-1 language code for the service category name, or null if not present. - * @return a two-digit ISO-639-1 language code, e.g. "en" for English - */ - public String getLanguageCode() { - return mLanguage; - } - - /** - * Returns the maximum number of messages to store for this service category. - * @return the maximum number of messages to store for this service category - */ - public int getMaxMessages() { - return mMaxMessages; - } - - /** - * Returns the service category alert option, e.g. {@link #ALERT_OPTION_DEFAULT_ALERT}. - * @return one of the {@code ALERT_OPTION_*} values - */ - public int getAlertOption() { - return mAlertOption; - } - - /** - * Returns the service category name, in the language specified by {@link #getLanguageCode()}. - * @return an optional service category name - */ - public String getCategoryName() { - return mCategoryName; - } - - @Override - public String toString() { - return "CdmaSmsCbProgramData{operation=" + mOperation + ", category=" + mCategory - + ", language=" + mLanguage + ", max messages=" + mMaxMessages - + ", alert option=" + mAlertOption + ", category name=" + mCategoryName + '}'; - } - - /** - * Describe the kinds of special objects contained in the marshalled representation. - * @return a bitmask indicating this Parcelable contains no special objects - */ - @Override - public int describeContents() { - return 0; - } - - /** Creator for unparcelling objects. */ - public static final Parcelable.Creator<CdmaSmsCbProgramData> - CREATOR = new Parcelable.Creator<CdmaSmsCbProgramData>() { - @Override - public CdmaSmsCbProgramData createFromParcel(Parcel in) { - return new CdmaSmsCbProgramData(in); - } - - @Override - public CdmaSmsCbProgramData[] newArray(int size) { - return new CdmaSmsCbProgramData[size]; - } - }; -} |