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