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