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 com.android.internal.telephony.cdma;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Parcel;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbCmasInfo;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbMessage;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.cdma.CdmaSmsCbProgramData;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.test.AndroidTestCase;
24ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog;
258fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajanimport android.test.suitebuilder.annotation.SmallTest;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.BearerData;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope;
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.UserData;
32d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.BitwiseOutputStream;
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
358fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajanimport org.junit.Test;
368fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.List;
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Random;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Test cases for basic SmsCbMessage operation for CDMA.
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class CdmaSmsCbTest extends AndroidTestCase {
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /* Copy of private subparameter identifier constants from BearerData class. */
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte SUBPARAM_MESSAGE_IDENTIFIER   = (byte) 0x00;
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte SUBPARAM_USER_DATA            = (byte) 0x01;
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte SUBPARAM_PRIORITY_INDICATOR   = (byte) 0x08;
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte SUBPARAM_LANGUAGE_INDICATOR   = (byte) 0x0D;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA    = 0x12;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Initialize a Parcel for an incoming CDMA cell broadcast. The caller will write the
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * bearer data and then convert it to an SmsMessage.
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param serviceCategory the CDMA service category
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the initialized Parcel
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static Parcel createBroadcastParcel(int serviceCategory) {
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = Parcel.obtain();
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(SmsEnvelope.TELESERVICE_NOT_SET);
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 1);  // non-zero for MESSAGE_TYPE_BROADCAST
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(serviceCategory);
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dummy address (RIL may generate a different dummy address for broadcasts)
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sAddress.number_of_digits
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt((byte) 0);       // sSubAddress.subaddressType
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sSubAddress.odd
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return p;
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Initialize a BitwiseOutputStream with the CDMA bearer data subparameters except for
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * user data. The caller will append the user data and add it to the parcel.
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param messageId the 16-bit message identifier
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param priority message priority
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param language message language code
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the initialized BitwiseOutputStream
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static BitwiseOutputStream createBearerDataStream(int messageId, int priority,
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int language) throws BitwiseOutputStream.AccessException {
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream bos = new BitwiseOutputStream(10);
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, 3);    // length: 3 bytes
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, BearerData.MESSAGE_TYPE_DELIVER);
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, ((messageId >>> 8) & 0xff));
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (messageId & 0xff));
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(1, 0);    // no User Data Header
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(3, 0);    // reserved
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (priority != -1) {
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, SUBPARAM_PRIORITY_INDICATOR);
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, 1);    // length: 1 byte
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(2, (priority & 0x03));
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(6, 0);    // reserved
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (language != -1) {
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, SUBPARAM_LANGUAGE_INDICATOR);
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, 1);    // length: 1 byte
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, (language & 0xff));
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return bos;
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Write the bearer data array to the parcel, then return a new SmsMessage from the parcel.
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param p the parcel containing the CDMA SMS headers
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param bearerData the bearer data byte array to append to the parcel
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the new SmsMessage created from the parcel
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static SmsMessage createMessageFromParcel(Parcel p, byte[] bearerData) {
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(bearerData.length);
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (byte b : bearerData) {
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            p.writeByte(b);
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.setDataPosition(0);   // reset position for reading
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage message = SmsMessage.newFromParcel(p);
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.recycle();
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return message;
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Create a parcel for an incoming CMAS broadcast, then return a new SmsMessage created
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from the parcel.
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param serviceCategory the CDMA service category
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param messageId the 16-bit message identifier
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param priority message priority
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param language message language code
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param body message body
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param cmasCategory CMAS category (or -1 to skip adding CMAS type 1 elements record)
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param responseType CMAS response type
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param severity CMAS severity
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param urgency CMAS urgency
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param certainty CMAS certainty
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the newly created SmsMessage object
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static SmsMessage createCmasSmsMessage(int serviceCategory, int messageId, int priority,
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int language, int encoding, String body, int cmasCategory, int responseType,
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int severity, int urgency, int certainty) throws Exception {
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream cmasBos = new BitwiseOutputStream(10);
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        cmasBos.write(8, 0);    // CMAE protocol version 0
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (body != null) {
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(8, 0);        // Type 0 elements (alert text)
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            encodeBody(encoding, body, true, cmasBos);
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (cmasCategory != SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN) {
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(8, 1);    // Type 1 elements
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(8, 4);    // length: 4 bytes
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(8, (cmasCategory & 0xff));
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(8, (responseType & 0xff));
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(4, (severity & 0x0f));
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(4, (urgency & 0x0f));
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(4, (certainty & 0x0f));
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            cmasBos.write(4, 0);    // pad to octet boundary
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] cmasUserData = cmasBos.toByteArray();
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = createBroadcastParcel(serviceCategory);
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, SUBPARAM_USER_DATA);
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, cmasUserData.length + 2);  // add 2 bytes for msg_encoding and num_fields
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(5, UserData.ENCODING_OCTET);
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, cmasUserData.length);
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.writeByteArray(cmasUserData.length * 8, cmasUserData);
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(3, 0);    // pad to byte boundary
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return createMessageFromParcel(p, bos.toByteArray());
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Create a parcel for an incoming CDMA cell broadcast, then return a new SmsMessage created
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * from the parcel.
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param serviceCategory the CDMA service category
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param messageId the 16-bit message identifier
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param priority message priority
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param language message language code
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param encoding user data encoding method
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param body the message body
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the newly created SmsMessage object
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static SmsMessage createBroadcastSmsMessage(int serviceCategory, int messageId,
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int priority, int language, int encoding, String body) throws Exception {
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = createBroadcastParcel(serviceCategory);
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, SUBPARAM_USER_DATA);
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        encodeBody(encoding, body, false, bos);
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return createMessageFromParcel(p, bos.toByteArray());
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Append the message length, encoding, and body to the BearerData output stream.
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * This is used for writing the User Data subparameter for non-CMAS broadcasts and for
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * writing the alert text for CMAS broadcasts.
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param encoding one of the CDMA UserData encoding values
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param body the message body
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param isCmasRecord true if this is a CMAS type 0 elements record; false for user data
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param bos the BitwiseOutputStream to write to
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @throws Exception on any encoding error
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void encodeBody(int encoding, String body, boolean isCmasRecord,
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            BitwiseOutputStream bos) throws Exception {
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (encoding == UserData.ENCODING_7BIT_ASCII || encoding == UserData.ENCODING_IA5) {
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int charCount = body.length();
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int padBits = (recordOctets * 8) - recordBits;
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                recordOctets++;                         // add 8 bits for num_fields
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, recordOctets);
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(5, (encoding & 0x1f));
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, charCount);
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < charCount; i++) {
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(7, body.charAt(i));
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(padBits, 0);      // pad to octet boundary
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (encoding == UserData.ENCODING_GSM_7BIT_ALPHABET
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                || encoding == UserData.ENCODING_GSM_DCS) {
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // convert to 7-bit packed encoding with septet count in index 0 of byte array
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] encodedBody = GsmAlphabet.stringToGsm7BitPacked(body);
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int charCount = encodedBody[0];             // septet count
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int padBits = (recordOctets * 8) - recordBits;
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                recordOctets++;                         // add 8 bits for num_fields
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (encoding == UserData.ENCODING_GSM_DCS) {
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    recordOctets++;                     // add 8 bits for DCS (message type)
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, recordOctets);
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(5, (encoding & 0x1f));
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord && encoding == UserData.ENCODING_GSM_DCS) {
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, 0);        // GSM DCS: 7 bit default alphabet, no msg class
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, charCount);
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] bodySeptets = Arrays.copyOfRange(encodedBody, 1, encodedBody.length);
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.writeByteArray(charCount * 7, bodySeptets);
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(padBits, 0);      // pad to octet boundary
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else if (encoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // 6 bit packed encoding with 0x20 offset (ASCII 0x20 - 0x60)
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int charCount = body.length();
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordBits = (charCount * 6) + 21;      // add 21 bits for header fields
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int padBits = (recordOctets * 8) - recordBits;
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, recordOctets);
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(5, (encoding & 0x1f));
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, UserData.IS91_MSG_TYPE_SHORT_MESSAGE);
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, charCount);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < charCount; i++) {
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(6, ((int) body.charAt(i) - 0x20));
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(padBits, 0);      // pad to octet boundary
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] encodedBody;
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            switch (encoding) {
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case UserData.ENCODING_UNICODE_16:
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    encodedBody = body.getBytes("UTF-16BE");
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case UserData.ENCODING_SHIFT_JIS:
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    encodedBody = body.getBytes("Shift_JIS");
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case UserData.ENCODING_KOREAN:
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    encodedBody = body.getBytes("KSC5601");
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case UserData.ENCODING_LATIN_HEBREW:
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    encodedBody = body.getBytes("ISO-8859-8");
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                case UserData.ENCODING_LATIN:
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                default:
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    encodedBody = body.getBytes("ISO-8859-1");
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    break;
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int charCount = body.length();              // use actual char count for num fields
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int recordOctets = encodedBody.length + 1;  // add 1 byte for encoding and pad bits
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                recordOctets++;                         // add 8 bits for num_fields
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(8, recordOctets);
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(5, (encoding & 0x1f));
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (!isCmasRecord) {
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, charCount);
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.writeByteArray(encodedBody.length * 8, encodedBody);
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(3, 0);            // pad to octet boundary
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String TEST_TEXT = "This is a test CDMA cell broadcast message..."
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + "678901234567890123456789012345678901234567890";
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String PRES_ALERT =
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            "THE PRESIDENT HAS ISSUED AN EMERGENCY ALERT. CHECK LOCAL MEDIA FOR MORE DETAILS";
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String EXTREME_ALERT = "FLASH FLOOD WARNING FOR SOUTH COCONINO COUNTY"
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + " - NORTH CENTRAL ARIZONA UNTIL 415 PM MST";
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String SEVERE_ALERT = "SEVERE WEATHER WARNING FOR SOMERSET COUNTY"
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + " - NEW JERSEY UNTIL 415 PM MST";
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String AMBER_ALERT =
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            "AMBER ALERT:Mountain View,CA VEH'07 Blue Honda Civic CA LIC 5ABC123";
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String MONTHLY_TEST_ALERT = "This is a test of the emergency alert system."
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            + " This is only a test. 89012345678901234567890";
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String IS91_TEXT = "IS91 SHORT MSG";   // max length 14 chars
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Verify that the SmsCbMessage has the correct values for CDMA.
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param cbMessage the message to test
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void verifyCbValues(SmsCbMessage cbMessage) {
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_FORMAT_3GPP2, cbMessage.getMessageFormat());
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, cbMessage.getGeographicalScope());
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(false, cbMessage.isEtwsMessage()); // ETWS on CDMA not currently supported
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void doTestNonEmergencyBroadcast(int encoding) throws Exception {
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createBroadcastSmsMessage(123, 456, BearerData.PRIORITY_NORMAL,
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT);
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        verifyCbValues(cbMessage);
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(123, cbMessage.getServiceCategory());
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(456, cbMessage.getSerialNumber());
3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("en", cbMessage.getLanguageCode());
3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(TEST_TEXT, cbMessage.getMessageBody());
3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(false, cbMessage.isEmergencyMessage());
3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(false, cbMessage.isCmasMessage());
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3708fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testNonEmergencyBroadcast7bitAscii() throws Exception {
3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestNonEmergencyBroadcast(UserData.ENCODING_7BIT_ASCII);
3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3758fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testNonEmergencyBroadcast7bitGsm() throws Exception {
3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestNonEmergencyBroadcast(UserData.ENCODING_GSM_7BIT_ALPHABET);
3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3808fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testNonEmergencyBroadcast16bitUnicode() throws Exception {
3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestNonEmergencyBroadcast(UserData.ENCODING_UNICODE_16);
3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3858fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testNonEmergencyBroadcastIs91Extended() throws Exception {
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // IS-91 doesn't support language or priority subparameters, max 14 chars text
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createBroadcastSmsMessage(987, 654, -1, -1,
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_IS91_EXTENDED_PROTOCOL, IS91_TEXT);
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        verifyCbValues(cbMessage);
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(987, cbMessage.getServiceCategory());
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(654, cbMessage.getSerialNumber());
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(null, cbMessage.getLanguageCode());
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(IS91_TEXT, cbMessage.getMessageBody());
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(false, cbMessage.isEmergencyMessage());
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(false, cbMessage.isCmasMessage());
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void doTestCmasBroadcast(int serviceCategory, int messageClass, String body)
4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throws Exception {
4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createCmasSmsMessage(
4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                serviceCategory, 1234, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1);
4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        verifyCbValues(cbMessage);
4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(serviceCategory, cbMessage.getServiceCategory());
4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(1234, cbMessage.getSerialNumber());
4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("en", cbMessage.getLanguageCode());
4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(body, cbMessage.getMessageBody());
4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isEmergencyMessage());
4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isCmasMessage());
4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(messageClass, cmasInfo.getMessageClass());
4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4268fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasPresidentialAlert() throws Exception {
4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, PRES_ALERT);
4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4328fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasExtremeAlert() throws Exception {
4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, EXTREME_ALERT);
4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4388fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasSevereAlert() throws Exception {
4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT, SEVERE_ALERT);
4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4448fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasAmberAlert() throws Exception {
4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY, AMBER_ALERT);
4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4508fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasTestMessage() throws Exception {
4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST, MONTHLY_TEST_ALERT);
4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4568fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasExtremeAlertType1Elements() throws Exception {
4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                5678, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_7BIT_ASCII, EXTREME_ALERT, SmsCbCmasInfo.CMAS_CATEGORY_ENV,
4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, SmsCbCmasInfo.CMAS_SEVERITY_SEVERE,
4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        verifyCbValues(cbMessage);
4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cbMessage.getServiceCategory());
4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(5678, cbMessage.getSerialNumber());
4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("en", cbMessage.getLanguageCode());
4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(EXTREME_ALERT, cbMessage.getMessageBody());
4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isEmergencyMessage());
4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isCmasMessage());
4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass());
4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_ENV, cmasInfo.getCategory());
4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, cmasInfo.getResponseType());
4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, cmasInfo.getSeverity());
4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, cmasInfo.getUrgency());
4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, cmasInfo.getCertainty());
4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // VZW requirement is to discard message with unsupported charset. Verify that we return null
4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // for this unsupported character set.
4858fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasUnsupportedCharSet() throws Exception {
4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                12345, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_GSM_DCS, EXTREME_ALERT, -1, -1, -1, -1, -1);
4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNull("expected null for unsupported charset", cbMessage);
4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // VZW requirement is to discard message with unsupported charset. Verify that we return null
4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // for this unsupported character set.
4978fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasUnsupportedCharSet2() throws Exception {
4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                67890, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1);
5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNull("expected null for unsupported charset", cbMessage);
5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // VZW requirement is to discard message without record type 0. The framework will decode it
5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // and the app will discard it.
5098fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testCmasNoRecordType0() throws Exception {
5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createCmasSmsMessage(
5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, 1234,
5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                UserData.ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1);
5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        verifyCbValues(cbMessage);
5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                cbMessage.getServiceCategory());
5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(1234, cbMessage.getSerialNumber());
5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("en", cbMessage.getLanguageCode());
5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(null, cbMessage.getMessageBody());
5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isEmergencyMessage());
5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(true, cbMessage.isCmasMessage());
5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, cmasInfo.getMessageClass());
5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Make sure we don't throw an exception if we feed completely random data to BearerStream.
5368fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testRandomBearerStreamData() {
5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Random r = new Random(54321);
5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int run = 0; run < 1000; run++) {
5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int len = r.nextInt(140);
5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            byte[] data = new byte[len];
5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            for (int i = 0; i < len; i++) {
5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                data[i] = (byte) r.nextInt(256);
5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
545ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            // Rlog.d("CdmaSmsCbTest", "trying random bearer data run " + run + " length " + len);
5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                Parcel p = createBroadcastParcel(category);
5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsMessage msg = createMessageFromParcel(p, data);
5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbMessage cbMessage = msg.parseBroadcastSms();
5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // with random input, cbMessage will almost always be null (log when it isn't)
5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (cbMessage != null) {
553ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                    Rlog.d("CdmaSmsCbTest", "success: " + cbMessage);
5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (Exception e) {
556ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.d("CdmaSmsCbTest", "exception thrown", e);
5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Make sure we don't throw an exception if we put random data in the UserData subparam.
5638fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testRandomUserData() {
5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Random r = new Random(94040);
5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int run = 0; run < 1000; run++) {
5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            Parcel p = createBroadcastParcel(category);
5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int len = r.nextInt(140);
570ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville            // Rlog.d("CdmaSmsCbTest", "trying random user data run " + run + " length " + len);
5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                BitwiseOutputStream bos = createBearerDataStream(r.nextInt(65536), r.nextInt(4),
5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        r.nextInt(256));
5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, SUBPARAM_USER_DATA);
5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                bos.write(8, len);
5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                for (int i = 0; i < len; i++) {
5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    bos.write(8, r.nextInt(256));
5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbMessage cbMessage = msg.parseBroadcastSms();
5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (Exception e) {
586ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville                Rlog.d("CdmaSmsCbTest", "exception thrown", e);
5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Initialize a Parcel for incoming Service Category Program Data teleservice. The caller will
5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * write the bearer data and then convert it to an SmsMessage.
5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return the initialized Parcel
5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static Parcel createServiceCategoryProgramDataParcel() {
5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = Parcel.obtain();
5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(SmsEnvelope.TELESERVICE_SCPT);
6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);  // non-zero for MESSAGE_TYPE_BROADCAST
6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(0);
6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // dummy address (RIL may generate a different dummy address for broadcasts)
6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sAddress.number_of_digits
6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeInt((byte) 0);       // sSubAddress.subaddressType
6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sSubAddress.odd
6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return p;
6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String CAT_EXTREME_THREAT = "Extreme Threat to Life and Property";
6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String CAT_SEVERE_THREAT = "Severe Threat to Life and Property";
6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String CAT_AMBER_ALERTS = "AMBER Alerts";
6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6208fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testServiceCategoryProgramDataAddCategory() throws Exception {
6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = createServiceCategoryProgramDataParcel();
6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream bos = createBearerDataStream(123, -1, -1);
6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int categoryNameLength = CAT_EXTREME_THREAT.length();
6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamLengthBits = (53 + (categoryNameLength * 7));
6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, subparamLengthBytes);
6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(5, UserData.ENCODING_7BIT_ASCII);
6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY);
6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT >>> 8));
6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT & 0xff));
6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, BearerData.LANGUAGE_ENGLISH);
6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, 100);  // max messages
6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT);
6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, categoryNameLength);
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < categoryNameLength; i++) {
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(7, CAT_EXTREME_THREAT.charAt(i));
6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(subparamPadBits, 0);
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull(msg);
6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.parseSms();
6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull(programDataList);
6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(1, programDataList.size());
6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CdmaSmsCbProgramData programData = programDataList.get(0);
6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation());
6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory());
6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName());
657b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(100, programData.getMaxMessages());
6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption());
6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6628fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testServiceCategoryProgramDataDeleteTwoCategories() throws Exception {
6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = createServiceCategoryProgramDataParcel();
6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        BitwiseOutputStream bos = createBearerDataStream(456, -1, -1);
6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int category1NameLength = CAT_SEVERE_THREAT.length();
6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int category2NameLength = CAT_AMBER_ALERTS.length();
6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamLengthBits = (101 + (category1NameLength * 7) + (category2NameLength * 7));
6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;
6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, subparamLengthBytes);
6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(5, UserData.ENCODING_7BIT_ASCII);
6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT >>> 8));
6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT & 0xff));
6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, BearerData.LANGUAGE_ENGLISH);
6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, 0);  // max messages
6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, category1NameLength);
6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < category1NameLength; i++) {
6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(7, CAT_SEVERE_THREAT.charAt(i));
6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY >>> 8));
6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY & 0xff));
6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, BearerData.LANGUAGE_ENGLISH);
6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, 0);  // max messages
6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);
6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(8, category2NameLength);
6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < category2NameLength; i++) {
6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            bos.write(7, CAT_AMBER_ALERTS.charAt(i));
7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        bos.write(subparamPadBits, 0);
7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull(msg);
7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        msg.parseSms();
7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull(programDataList);
7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(2, programDataList.size());
7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        CdmaSmsCbProgramData programData = programDataList.get(0);
7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory());
7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName());
715b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0, programData.getMaxMessages());
7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        programData = programDataList.get(1);
7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                programData.getCategory());
7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName());
724b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0, programData.getMaxMessages());
7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final byte[] CMAS_TEST_BEARER_DATA = {
7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x00, 0x03, 0x1C, 0x78, 0x00, 0x01, 0x59, 0x02, (byte) 0xB8, 0x00, 0x02, 0x10, (byte) 0xAA,
7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x68, (byte) 0xD3, (byte) 0xCD, 0x06, (byte) 0x9E, 0x68, 0x30, (byte) 0xA0, (byte) 0xE9,
7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        (byte) 0x97, (byte) 0x9F, 0x44, 0x1B, (byte) 0xF3, 0x20, (byte) 0xE9, (byte) 0xA3,
7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x2A, 0x08, 0x7B, (byte) 0xF6, (byte) 0xED, (byte) 0xCB, (byte) 0xCB, 0x1E, (byte) 0x9C,
7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x3B, 0x10, 0x4D, (byte) 0xDF, (byte) 0x8B, 0x4E,
7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        (byte) 0xCC, (byte) 0xA8, 0x20, (byte) 0xEC, (byte) 0xCB, (byte) 0xCB, (byte) 0xA2, 0x0A,
7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x7E, 0x79, (byte) 0xF4, (byte) 0xCB, (byte) 0xB5, 0x72, 0x0A, (byte) 0x9A, 0x34,
7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        (byte) 0xF3, 0x41, (byte) 0xA7, (byte) 0x9A, 0x0D, (byte) 0xFB, (byte) 0xB6, 0x79, 0x41,
7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        (byte) 0x85, 0x07, 0x4C, (byte) 0xBC, (byte) 0xFA, 0x2E, 0x00, 0x08, 0x20, 0x58, 0x38,
7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        (byte) 0x88, (byte) 0x80, 0x10, 0x54, 0x06, 0x38, 0x20, 0x60,
7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        0x30, (byte) 0xA8, (byte) 0x81, (byte) 0x90, 0x20, 0x08
7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    };
7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // Test case for CMAS test message received on the Sprint network.
7448fa6dfb2cbdc35ea4d70add3f8d9172d2e18d650Amit Mahajan    @Test @SmallTest
7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testDecodeRawBearerData() throws Exception {
7460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        Parcel p = createBroadcastParcel(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsMessage msg = createMessageFromParcel(p, CMAS_TEST_BEARER_DATA);
7480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbMessage cbMessage = msg.parseBroadcastSms();
7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull("expected non-null for bearer data", cbMessage);
7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("geoScope", cbMessage.getGeographicalScope(), 1);
7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072);
7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("serviceCategory", cbMessage.getServiceCategory(),
7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("payload", cbMessage.getMessageBody(),
7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                "This is a test of the Commercial Mobile Alert System. This is only a test.");
7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertNotNull("expected non-null for CMAS info", cmasInfo);
7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("category", cmasInfo.getCategory(), SmsCbCmasInfo.CMAS_CATEGORY_OTHER);
7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("responseType", cmasInfo.getResponseType(),
7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE);
7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("severity", cmasInfo.getSeverity(), SmsCbCmasInfo.CMAS_SEVERITY_SEVERE);
7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("urgency", cmasInfo.getUrgency(), SmsCbCmasInfo.CMAS_URGENCY_EXPECTED);
7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("certainty", cmasInfo.getCertainty(), SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
768