10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2010 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 com.android.internal.telephony.gsm; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbCmasInfo; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbEtwsInfo; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * CellBroadcastReceiver test cases, but should not be used by applications. 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * All relevant header information is now sent as a Parcelable 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link android.telephony.SmsCbMessage} object in the "message" extra of the 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent. 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The raw PDU is no longer sent to SMS CB applications. 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleclass SmsCbHeader { 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Length of SMS-CB header 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int PDU_HEADER_LENGTH = 6; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int FORMAT_GSM = 1; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int FORMAT_UMTS = 2; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static final int FORMAT_ETWS_PRIMARY = 3; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Message type value as defined in 3gpp TS 25.324, section 11.1. 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int MESSAGE_TYPE_CBS_MESSAGE = 1; 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Length of GSM pdus 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int PDU_LENGTH_GSM = 88; 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Maximum length of ETWS primary message GSM pdus 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int PDU_LENGTH_ETWS = 56; 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int geographicalScope; 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** The serial number combines geographical scope, message code, and update number. */ 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int serialNumber; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** The Message Identifier in 3GPP is the same as the Service Category in CDMA. */ 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int messageIdentifier; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int dataCodingScheme; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int pageIndex; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int nrOfPages; 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final int format; 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** ETWS warning notification info. */ 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final SmsCbEtwsInfo mEtwsInfo; 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** CMAS warning notification info. */ 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final SmsCbCmasInfo mCmasInfo; 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsCbHeader(byte[] pdu) throws IllegalArgumentException { 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pdu == null || pdu.length < PDU_HEADER_LENGTH) { 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new IllegalArgumentException("Illegal PDU"); 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9844be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks if (pdu.length <= PDU_LENGTH_GSM) { 9944be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // can be ETWS or GSM format. 10044be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // Per TS23.041 9.4.1.2 and 9.4.1.3.2, GSM and ETWS format both 10144be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // contain serial number which contains GS, Message Code, and Update Number 10244be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // per 9.4.1.2.1, and message identifier in same octets 10344be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks geographicalScope = (pdu[0] & 0xc0) >>> 6; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville serialNumber = ((pdu[0] & 0xff) << 8) | (pdu[1] & 0xff); 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville messageIdentifier = ((pdu[2] & 0xff) << 8) | (pdu[3] & 0xff); 10644be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks if (isEtwsMessage() && pdu.length <= PDU_LENGTH_ETWS) { 10744be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks format = FORMAT_ETWS_PRIMARY; 10844be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks dataCodingScheme = -1; 10944be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks pageIndex = -1; 11044be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks nrOfPages = -1; 11144be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks boolean emergencyUserAlert = (pdu[4] & 0x1) != 0; 11244be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks boolean activatePopup = (pdu[5] & 0x80) != 0; 11344be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks int warningType = (pdu[4] & 0xfe) >>> 1; 11444be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks byte[] warningSecurityInfo; 11544be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // copy the Warning-Security-Information, if present 11644be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks if (pdu.length > PDU_HEADER_LENGTH) { 11744be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks warningSecurityInfo = Arrays.copyOfRange(pdu, 6, pdu.length); 11844be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks } else { 11944be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks warningSecurityInfo = null; 12044be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks } 12144be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, 12244be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks warningSecurityInfo); 12344be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks mCmasInfo = null; 12444be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks return; // skip the ETWS/CMAS initialization code for regular notifications 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 12644be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // GSM pdus are no more than 88 bytes 12744be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks format = FORMAT_GSM; 12844be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks dataCodingScheme = pdu[4] & 0xff; 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 13044be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks // Check for invalid page parameter 13144be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks int pageIndex = (pdu[5] & 0xf0) >>> 4; 13244be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks int nrOfPages = pdu[5] & 0x0f; 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 13444be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks if (pageIndex == 0 || nrOfPages == 0 || pageIndex > nrOfPages) { 13544be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks pageIndex = 1; 13644be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks nrOfPages = 1; 13744be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks } 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 13944be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks this.pageIndex = pageIndex; 14044be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks this.nrOfPages = nrOfPages; 14144be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks } 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // UMTS pdus are always at least 90 bytes since the payload includes 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // a number-of-pages octet and also one length octet per page 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville format = FORMAT_UMTS; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int messageType = pdu[0]; 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (messageType != MESSAGE_TYPE_CBS_MESSAGE) { 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new IllegalArgumentException("Unsupported message type " + messageType); 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville messageIdentifier = ((pdu[1] & 0xff) << 8) | pdu[2] & 0xff; 15444be3fc486c049bbfea331b0fc2cff0552326f4bRika Brooks geographicalScope = (pdu[3] & 0xc0) >>> 6; 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville serialNumber = ((pdu[3] & 0xff) << 8) | (pdu[4] & 0xff); 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dataCodingScheme = pdu[5] & 0xff; 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // We will always consider a UMTS message as having one single page 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // since there's only one instance of the header, even though the 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // actual payload may contain several pages. 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pageIndex = 1; 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville nrOfPages = 1; 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (isEtwsMessage()) { 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean emergencyUserAlert = isEtwsEmergencyUserAlert(); 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean activatePopup = isEtwsPopupAlert(); 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int warningType = getEtwsWarningType(); 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEtwsInfo = new SmsCbEtwsInfo(warningType, emergencyUserAlert, activatePopup, null); 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmasInfo = null; 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (isCmasMessage()) { 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int messageClass = getCmasMessageClass(); 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int severity = getCmasSeverity(); 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int urgency = getCmasUrgency(); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int certainty = getCmasCertainty(); 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEtwsInfo = null; 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmasInfo = new SmsCbCmasInfo(messageClass, SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, severity, urgency, certainty); 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEtwsInfo = null; 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCmasInfo = null; 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getGeographicalScope() { 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return geographicalScope; 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getSerialNumber() { 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return serialNumber; 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getServiceCategory() { 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return messageIdentifier; 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getDataCodingScheme() { 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dataCodingScheme; 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getPageIndex() { 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return pageIndex; 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int getNumberOfPages() { 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return nrOfPages; 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbEtwsInfo getEtwsInfo() { 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mEtwsInfo; 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbCmasInfo getCmasInfo() { 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mCmasInfo; 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether this broadcast is an emergency (PWS) message type. 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if this message is emergency type; false otherwise 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isEmergencyMessage() { 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return messageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && messageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER; 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether this broadcast is an ETWS emergency message type. 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if this message is ETWS emergency type; false otherwise 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean isEtwsMessage() { 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (messageIdentifier & SmsCbConstants.MESSAGE_ID_ETWS_TYPE_MASK) 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville == SmsCbConstants.MESSAGE_ID_ETWS_TYPE; 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether this broadcast is an ETWS primary notification. 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if this message is an ETWS primary notification; false otherwise 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isEtwsPrimaryNotification() { 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return format == FORMAT_ETWS_PRIMARY; 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether this broadcast is in UMTS format. 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if this message is in UMTS format; false otherwise 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean isUmtsFormat() { 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return format == FORMAT_UMTS; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether this message is a CMAS emergency message type. 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if this message is CMAS emergency type; false otherwise 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean isCmasMessage() { 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return messageIdentifier >= SmsCbConstants.MESSAGE_ID_CMAS_FIRST_IDENTIFIER 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville && messageIdentifier <= SmsCbConstants.MESSAGE_ID_CMAS_LAST_IDENTIFIER; 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether the popup alert flag is set for an ETWS warning notification. 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for ETWS type. 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if the message code indicates a popup alert should be displayed 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean isEtwsPopupAlert() { 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_ACTIVATE_POPUP) != 0; 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return whether the emergency user alert flag is set for an ETWS warning notification. 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for ETWS type. 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if the message code indicates an emergency user alert 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean isEtwsEmergencyUserAlert() { 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (serialNumber & SmsCbConstants.SERIAL_NUMBER_ETWS_EMERGENCY_USER_ALERT) != 0; 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the warning type for an ETWS warning notification. 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for ETWS type. 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the ETWS warning type defined in 3GPP TS 23.041 section 9.3.24 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int getEtwsWarningType() { 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return messageIdentifier - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING; 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the message class for a CMAS warning notification. 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for CMAS type. 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the CMAS message class as defined in {@link SmsCbCmasInfo} 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int getCmasMessageClass() { 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (messageIdentifier) { 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL: 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT; 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT; 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT; 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY: 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY; 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST: 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST; 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE: 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE; 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE: 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE; 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN; 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the severity for a CMAS warning notification. This is only available for extreme 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and severe alerts, not for other types such as Presidential Level and AMBER alerts. 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for CMAS type. 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the CMAS severity as defined in {@link SmsCbCmasInfo} 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int getCmasSeverity() { 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (messageIdentifier) { 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_SEVERITY_EXTREME; 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_SEVERITY_SEVERE; 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the urgency for a CMAS warning notification. This is only available for extreme 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and severe alerts, not for other types such as Presidential Level and AMBER alerts. 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for CMAS type. 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the CMAS urgency as defined in {@link SmsCbCmasInfo} 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int getCmasUrgency() { 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (messageIdentifier) { 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE; 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_URGENCY_EXPECTED; 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the certainty for a CMAS warning notification. This is only available for extreme 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and severe alerts, not for other types such as Presidential Level and AMBER alerts. 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This method assumes that the message ID has already been checked for CMAS type. 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the CMAS certainty as defined in {@link SmsCbCmasInfo} 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int getCmasCertainty() { 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (messageIdentifier) { 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED; 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY; 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String toString() { 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return "SmsCbHeader{GS=" + geographicalScope + ", serialNumber=0x" + 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Integer.toHexString(serialNumber) + 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ", messageIdentifier=0x" + Integer.toHexString(messageIdentifier) + 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ", DCS=0x" + Integer.toHexString(dataCodingScheme) + 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ", page " + pageIndex + " of " + nrOfPages + '}'; 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 413