10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2012 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage android.telephony; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Parcel; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Parcelable; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.format.Time; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 23d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Contains information elements for a GSM or UMTS ETWS warning notification. 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Supported values for each element are defined in 3GPP TS 23.041. 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class SmsCbEtwsInfo implements Parcelable { 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning type for earthquake. */ 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning type for tsunami. */ 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning type for earthquake and tsunami. */ 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning type for test messages. */ 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning type for other emergency types. */ 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Unknown ETWS warning type. */ 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** One of the ETWS warning type constants defined in this class. */ 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int mWarningType; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Whether or not to activate the emergency user alert tone and vibration. */ 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final boolean mEmergencyUserAlert; 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Whether or not to activate a popup alert. */ 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final boolean mActivatePopup; 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 50-byte security information (ETWS primary notification for GSM only). As of Release 10, 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and digital signature if received. Therefore it is treated as a raw byte array and 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * parceled with the broadcast intent if present, but the timestamp is only computed if an 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * application asks for the individual components. 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final byte[] mWarningSecurityInformation; 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Create a new SmsCbEtwsInfo object with the specified values. */ 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup, 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] warningSecurityInformation) { 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mWarningType = warningType; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEmergencyUserAlert = emergencyUserAlert; 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mActivatePopup = activatePopup; 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mWarningSecurityInformation = warningSecurityInformation; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Create a new SmsCbEtwsInfo object from a Parcel. */ 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbEtwsInfo(Parcel in) { 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mWarningType = in.readInt(); 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEmergencyUserAlert = (in.readInt() != 0); 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mActivatePopup = (in.readInt() != 0); 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mWarningSecurityInformation = in.createByteArray(); 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Flatten this object into a Parcel. 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param dest The Parcel in which the object should be written. 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param flags Additional flags about how the object should be written (ignored). 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void writeToParcel(Parcel dest, int flags) { 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dest.writeInt(mWarningType); 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dest.writeInt(mEmergencyUserAlert ? 1 : 0); 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dest.writeInt(mActivatePopup ? 1 : 0); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dest.writeByteArray(mWarningSecurityInformation); 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the ETWS warning type. 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE} 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getWarningType() { 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mWarningType; 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the ETWS emergency user alert flag. 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true to notify terminal to activate emergency user alert; false otherwise 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isEmergencyUserAlert() { 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mEmergencyUserAlert; 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the ETWS activate popup flag. 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true to notify terminal to activate display popup; false otherwise 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isPopupAlert() { 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mActivatePopup; 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the Warning-Security-Information timestamp (GSM primary notifications only). 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public long getPrimaryNotificationTimestamp() { 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]); 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]); 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]); 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]); 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]); 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]); 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // For the timezone, the most significant bit of the 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // least significant nibble is the sign byte 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (meaning the max range of this field is 79 quarter-hours, 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // which is more than enough) 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte tzByte = mWarningSecurityInformation[6]; 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Mask out sign bit. 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Time time = new Time(Time.TIMEZONE_UTC); 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We only need to support years above 2000. 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.year = year + 2000; 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.month = month - 1; 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.monthDay = day; 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.hour = hour; 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.minute = minute; 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville time.second = second; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Timezone offset is in quarter hours. 166cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville return time.toMillis(true) - timezoneOffset * 15 * 60 * 1000; 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the digital signature (GSM primary notifications only). As of Release 10, 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3GPP TS 23.041 states that the UE shall ignore this value if received. 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a byte array containing a copy of the primary notification digital signature 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public byte[] getPrimaryNotificationSignature() { 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) { 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50); 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String toString() { 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert=" 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}'; 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Describe the kinds of special objects contained in the marshalled representation. 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a bitmask indicating this Parcelable contains no special objects 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int describeContents() { 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Creator for unparcelling objects. */ 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() { 198cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsCbEtwsInfo createFromParcel(Parcel in) { 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new SmsCbEtwsInfo(in); 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 203cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsCbEtwsInfo[] newArray(int size) { 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new SmsCbEtwsInfo[size]; 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville }; 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 209