FileDocCategorySizeDatePackage
CdmaSmsCbTest.javaAPI DocAndroid 5.1 API36441Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony.cdma

CdmaSmsCbTest

public class CdmaSmsCbTest extends android.test.AndroidTestCase
Test cases for basic SmsCbMessage operation for CDMA.

Fields Summary
private static final byte
SUBPARAM_MESSAGE_IDENTIFIER
private static final byte
SUBPARAM_USER_DATA
private static final byte
SUBPARAM_PRIORITY_INDICATOR
private static final byte
SUBPARAM_LANGUAGE_INDICATOR
private static final byte
SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA
private static final String
TEST_TEXT
private static final String
PRES_ALERT
private static final String
EXTREME_ALERT
private static final String
SEVERE_ALERT
private static final String
AMBER_ALERT
private static final String
MONTHLY_TEST_ALERT
private static final String
IS91_TEXT
private static final String
CAT_EXTREME_THREAT
private static final String
CAT_SEVERE_THREAT
private static final String
CAT_AMBER_ALERTS
private static final byte[]
CMAS_TEST_BEARER_DATA
Constructors Summary
Methods Summary
private static com.android.internal.util.BitwiseOutputStreamcreateBearerDataStream(int messageId, int priority, int language)
Initialize a BitwiseOutputStream with the CDMA bearer data subparameters except for user data. The caller will append the user data and add it to the parcel.

param
messageId the 16-bit message identifier
param
priority message priority
param
language message language code
return
the initialized BitwiseOutputStream

        BitwiseOutputStream bos = new BitwiseOutputStream(10);
        bos.write(8, SUBPARAM_MESSAGE_IDENTIFIER);
        bos.write(8, 3);    // length: 3 bytes
        bos.write(4, BearerData.MESSAGE_TYPE_DELIVER);
        bos.write(8, ((messageId >>> 8) & 0xff));
        bos.write(8, (messageId & 0xff));
        bos.write(1, 0);    // no User Data Header
        bos.write(3, 0);    // reserved

        if (priority != -1) {
            bos.write(8, SUBPARAM_PRIORITY_INDICATOR);
            bos.write(8, 1);    // length: 1 byte
            bos.write(2, (priority & 0x03));
            bos.write(6, 0);    // reserved
        }

        if (language != -1) {
            bos.write(8, SUBPARAM_LANGUAGE_INDICATOR);
            bos.write(8, 1);    // length: 1 byte
            bos.write(8, (language & 0xff));
        }

        return bos;
    
private static android.os.ParcelcreateBroadcastParcel(int serviceCategory)
Initialize a Parcel for an incoming CDMA cell broadcast. The caller will write the bearer data and then convert it to an SmsMessage.

param
serviceCategory the CDMA service category
return
the initialized Parcel


                                          
         
        Parcel p = Parcel.obtain();

        p.writeInt(SmsEnvelope.TELESERVICE_NOT_SET);
        p.writeByte((byte) 1);  // non-zero for MESSAGE_TYPE_BROADCAST
        p.writeInt(serviceCategory);

        // dummy address (RIL may generate a different dummy address for broadcasts)
        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
        p.writeByte((byte) 0);      // sAddress.number_of_digits
        p.writeInt((byte) 0);       // sSubAddress.subaddressType
        p.writeByte((byte) 0);      // sSubAddress.odd
        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
        return p;
    
private static SmsMessagecreateBroadcastSmsMessage(int serviceCategory, int messageId, int priority, int language, int encoding, java.lang.String body)
Create a parcel for an incoming CDMA cell broadcast, then return a new SmsMessage created from the parcel.

param
serviceCategory the CDMA service category
param
messageId the 16-bit message identifier
param
priority message priority
param
language message language code
param
encoding user data encoding method
param
body the message body
return
the newly created SmsMessage object

        Parcel p = createBroadcastParcel(serviceCategory);
        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);

        bos.write(8, SUBPARAM_USER_DATA);
        encodeBody(encoding, body, false, bos);

        return createMessageFromParcel(p, bos.toByteArray());
    
private static SmsMessagecreateCmasSmsMessage(int serviceCategory, int messageId, int priority, int language, int encoding, java.lang.String body, int cmasCategory, int responseType, int severity, int urgency, int certainty)
Create a parcel for an incoming CMAS broadcast, then return a new SmsMessage created from the parcel.

param
serviceCategory the CDMA service category
param
messageId the 16-bit message identifier
param
priority message priority
param
language message language code
param
body message body
param
cmasCategory CMAS category (or -1 to skip adding CMAS type 1 elements record)
param
responseType CMAS response type
param
severity CMAS severity
param
urgency CMAS urgency
param
certainty CMAS certainty
return
the newly created SmsMessage object

        BitwiseOutputStream cmasBos = new BitwiseOutputStream(10);
        cmasBos.write(8, 0);    // CMAE protocol version 0

        if (body != null) {
            cmasBos.write(8, 0);        // Type 0 elements (alert text)
            encodeBody(encoding, body, true, cmasBos);
        }

        if (cmasCategory != SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN) {
            cmasBos.write(8, 1);    // Type 1 elements
            cmasBos.write(8, 4);    // length: 4 bytes
            cmasBos.write(8, (cmasCategory & 0xff));
            cmasBos.write(8, (responseType & 0xff));
            cmasBos.write(4, (severity & 0x0f));
            cmasBos.write(4, (urgency & 0x0f));
            cmasBos.write(4, (certainty & 0x0f));
            cmasBos.write(4, 0);    // pad to octet boundary
        }

        byte[] cmasUserData = cmasBos.toByteArray();

        Parcel p = createBroadcastParcel(serviceCategory);
        BitwiseOutputStream bos = createBearerDataStream(messageId, priority, language);

        bos.write(8, SUBPARAM_USER_DATA);
        bos.write(8, cmasUserData.length + 2);  // add 2 bytes for msg_encoding and num_fields
        bos.write(5, UserData.ENCODING_OCTET);
        bos.write(8, cmasUserData.length);
        bos.writeByteArray(cmasUserData.length * 8, cmasUserData);
        bos.write(3, 0);    // pad to byte boundary

        return createMessageFromParcel(p, bos.toByteArray());
    
private static SmsMessagecreateMessageFromParcel(android.os.Parcel p, byte[] bearerData)
Write the bearer data array to the parcel, then return a new SmsMessage from the parcel.

param
p the parcel containing the CDMA SMS headers
param
bearerData the bearer data byte array to append to the parcel
return
the new SmsMessage created from the parcel

        p.writeInt(bearerData.length);
        for (byte b : bearerData) {
            p.writeByte(b);
        }
        p.setDataPosition(0);   // reset position for reading
        SmsMessage message = SmsMessage.newFromParcel(p);
        p.recycle();
        return message;
    
private static android.os.ParcelcreateServiceCategoryProgramDataParcel()
Initialize a Parcel for incoming Service Category Program Data teleservice. The caller will write the bearer data and then convert it to an SmsMessage.

return
the initialized Parcel

        Parcel p = Parcel.obtain();

        p.writeInt(SmsEnvelope.TELESERVICE_SCPT);
        p.writeByte((byte) 0);  // non-zero for MESSAGE_TYPE_BROADCAST
        p.writeInt(0);

        // dummy address (RIL may generate a different dummy address for broadcasts)
        p.writeInt(CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF);            // sAddress.digit_mode
        p.writeInt(CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK);    // sAddress.number_mode
        p.writeInt(CdmaSmsAddress.TON_UNKNOWN);                     // sAddress.number_type
        p.writeInt(CdmaSmsAddress.NUMBERING_PLAN_ISDN_TELEPHONY);   // sAddress.number_plan
        p.writeByte((byte) 0);      // sAddress.number_of_digits
        p.writeInt((byte) 0);       // sSubAddress.subaddressType
        p.writeByte((byte) 0);      // sSubAddress.odd
        p.writeByte((byte) 0);      // sSubAddress.number_of_digits
        return p;
    
private static voiddoTestCmasBroadcast(int serviceCategory, int messageClass, java.lang.String body)

        SmsMessage msg = createCmasSmsMessage(
                serviceCategory, 1234, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
                UserData.ENCODING_7BIT_ASCII, body, -1, -1, -1, -1, -1);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        verifyCbValues(cbMessage);
        assertEquals(serviceCategory, cbMessage.getServiceCategory());
        assertEquals(1234, cbMessage.getSerialNumber());
        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
        assertEquals("en", cbMessage.getLanguageCode());
        assertEquals(body, cbMessage.getMessageBody());
        assertEquals(true, cbMessage.isEmergencyMessage());
        assertEquals(true, cbMessage.isCmasMessage());
        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
        assertEquals(messageClass, cmasInfo.getMessageClass());
        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
    
private static voiddoTestNonEmergencyBroadcast(int encoding)

        SmsMessage msg = createBroadcastSmsMessage(123, 456, BearerData.PRIORITY_NORMAL,
                BearerData.LANGUAGE_ENGLISH, encoding, TEST_TEXT);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        verifyCbValues(cbMessage);
        assertEquals(123, cbMessage.getServiceCategory());
        assertEquals(456, cbMessage.getSerialNumber());
        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
        assertEquals("en", cbMessage.getLanguageCode());
        assertEquals(TEST_TEXT, cbMessage.getMessageBody());
        assertEquals(false, cbMessage.isEmergencyMessage());
        assertEquals(false, cbMessage.isCmasMessage());
    
private static voidencodeBody(int encoding, java.lang.String body, boolean isCmasRecord, com.android.internal.util.BitwiseOutputStream bos)
Append the message length, encoding, and body to the BearerData output stream. This is used for writing the User Data subparameter for non-CMAS broadcasts and for writing the alert text for CMAS broadcasts.

param
encoding one of the CDMA UserData encoding values
param
body the message body
param
isCmasRecord true if this is a CMAS type 0 elements record; false for user data
param
bos the BitwiseOutputStream to write to
throws
Exception on any encoding error

        if (encoding == UserData.ENCODING_7BIT_ASCII || encoding == UserData.ENCODING_IA5) {
            int charCount = body.length();
            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
            int padBits = (recordOctets * 8) - recordBits;

            if (!isCmasRecord) {
                recordOctets++;                         // add 8 bits for num_fields
            }

            bos.write(8, recordOctets);
            bos.write(5, (encoding & 0x1f));

            if (!isCmasRecord) {
                bos.write(8, charCount);
            }

            for (int i = 0; i < charCount; i++) {
                bos.write(7, body.charAt(i));
            }

            bos.write(padBits, 0);      // pad to octet boundary
        } else if (encoding == UserData.ENCODING_GSM_7BIT_ALPHABET
                || encoding == UserData.ENCODING_GSM_DCS) {
            // convert to 7-bit packed encoding with septet count in index 0 of byte array
            byte[] encodedBody = GsmAlphabet.stringToGsm7BitPacked(body);

            int charCount = encodedBody[0];             // septet count
            int recordBits = (charCount * 7) + 5;       // add 5 bits for char set field
            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
            int padBits = (recordOctets * 8) - recordBits;

            if (!isCmasRecord) {
                recordOctets++;                         // add 8 bits for num_fields
                if (encoding == UserData.ENCODING_GSM_DCS) {
                    recordOctets++;                     // add 8 bits for DCS (message type)
                }
            }

            bos.write(8, recordOctets);
            bos.write(5, (encoding & 0x1f));

            if (!isCmasRecord && encoding == UserData.ENCODING_GSM_DCS) {
                bos.write(8, 0);        // GSM DCS: 7 bit default alphabet, no msg class
            }

            if (!isCmasRecord) {
                bos.write(8, charCount);
            }
            byte[] bodySeptets = Arrays.copyOfRange(encodedBody, 1, encodedBody.length);
            bos.writeByteArray(charCount * 7, bodySeptets);
            bos.write(padBits, 0);      // pad to octet boundary
        } else if (encoding == UserData.ENCODING_IS91_EXTENDED_PROTOCOL) {
            // 6 bit packed encoding with 0x20 offset (ASCII 0x20 - 0x60)
            int charCount = body.length();
            int recordBits = (charCount * 6) + 21;      // add 21 bits for header fields
            int recordOctets = (recordBits + 7) / 8;    // round up to octet boundary
            int padBits = (recordOctets * 8) - recordBits;

            bos.write(8, recordOctets);

            bos.write(5, (encoding & 0x1f));
            bos.write(8, UserData.IS91_MSG_TYPE_SHORT_MESSAGE);
            bos.write(8, charCount);

            for (int i = 0; i < charCount; i++) {
                bos.write(6, ((int) body.charAt(i) - 0x20));
            }

            bos.write(padBits, 0);      // pad to octet boundary
        } else {
            byte[] encodedBody;
            switch (encoding) {
                case UserData.ENCODING_UNICODE_16:
                    encodedBody = body.getBytes("UTF-16BE");
                    break;

                case UserData.ENCODING_SHIFT_JIS:
                    encodedBody = body.getBytes("Shift_JIS");
                    break;

                case UserData.ENCODING_KOREAN:
                    encodedBody = body.getBytes("KSC5601");
                    break;

                case UserData.ENCODING_LATIN_HEBREW:
                    encodedBody = body.getBytes("ISO-8859-8");
                    break;

                case UserData.ENCODING_LATIN:
                default:
                    encodedBody = body.getBytes("ISO-8859-1");
                    break;
            }
            int charCount = body.length();              // use actual char count for num fields
            int recordOctets = encodedBody.length + 1;  // add 1 byte for encoding and pad bits
            if (!isCmasRecord) {
                recordOctets++;                         // add 8 bits for num_fields
            }
            bos.write(8, recordOctets);
            bos.write(5, (encoding & 0x1f));
            if (!isCmasRecord) {
                bos.write(8, charCount);
            }
            bos.writeByteArray(encodedBody.length * 8, encodedBody);
            bos.write(3, 0);            // pad to octet boundary
        }
    
public voidtestCmasAmberAlert()

        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
                SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY, AMBER_ALERT);
    
public voidtestCmasExtremeAlert()

        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
                SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, EXTREME_ALERT);
    
public voidtestCmasExtremeAlertType1Elements()

        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
                5678, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
                UserData.ENCODING_7BIT_ASCII, EXTREME_ALERT, SmsCbCmasInfo.CMAS_CATEGORY_ENV,
                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, SmsCbCmasInfo.CMAS_SEVERITY_SEVERE,
                SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        verifyCbValues(cbMessage);
        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
                cbMessage.getServiceCategory());
        assertEquals(5678, cbMessage.getSerialNumber());
        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
        assertEquals("en", cbMessage.getLanguageCode());
        assertEquals(EXTREME_ALERT, cbMessage.getMessageBody());
        assertEquals(true, cbMessage.isEmergencyMessage());
        assertEquals(true, cbMessage.isCmasMessage());
        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
        assertEquals(SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT, cmasInfo.getMessageClass());
        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_ENV, cmasInfo.getCategory());
        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR, cmasInfo.getResponseType());
        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, cmasInfo.getSeverity());
        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, cmasInfo.getUrgency());
        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, cmasInfo.getCertainty());
    
public voidtestCmasNoRecordType0()

        SmsMessage msg = createCmasSmsMessage(
                SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, 1234,
                BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
                UserData.ENCODING_7BIT_ASCII, null, -1, -1, -1, -1, -1);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        verifyCbValues(cbMessage);
        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
                cbMessage.getServiceCategory());
        assertEquals(1234, cbMessage.getSerialNumber());
        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, cbMessage.getMessagePriority());
        assertEquals("en", cbMessage.getLanguageCode());
        assertEquals(null, cbMessage.getMessageBody());
        assertEquals(true, cbMessage.isEmergencyMessage());
        assertEquals(true, cbMessage.isCmasMessage());
        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
        assertEquals(SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, cmasInfo.getMessageClass());
        assertEquals(SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, cmasInfo.getCategory());
        assertEquals(SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, cmasInfo.getResponseType());
        assertEquals(SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, cmasInfo.getSeverity());
        assertEquals(SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, cmasInfo.getUrgency());
        assertEquals(SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, cmasInfo.getCertainty());
    
public voidtestCmasPresidentialAlert()

        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
                SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT, PRES_ALERT);
    
public voidtestCmasSevereAlert()

        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
                SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT, SEVERE_ALERT);
    
public voidtestCmasTestMessage()

        doTestCmasBroadcast(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
                SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST, MONTHLY_TEST_ALERT);
    
public voidtestCmasUnsupportedCharSet()

        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
                12345, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
                UserData.ENCODING_GSM_DCS, EXTREME_ALERT, -1, -1, -1, -1, -1);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        assertNull("expected null for unsupported charset", cbMessage);
    
public voidtestCmasUnsupportedCharSet2()

        SmsMessage msg = createCmasSmsMessage(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
                67890, BearerData.PRIORITY_EMERGENCY, BearerData.LANGUAGE_ENGLISH,
                UserData.ENCODING_KOREAN, EXTREME_ALERT, -1, -1, -1, -1, -1);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        assertNull("expected null for unsupported charset", cbMessage);
    
public voidtestDecodeRawBearerData()


    // Test case for CMAS test message received on the Sprint network.
         
        Parcel p = createBroadcastParcel(SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
        SmsMessage msg = createMessageFromParcel(p, CMAS_TEST_BEARER_DATA);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        assertNotNull("expected non-null for bearer data", cbMessage);
        assertEquals("geoScope", cbMessage.getGeographicalScope(), 1);
        assertEquals("serialNumber", cbMessage.getSerialNumber(), 51072);
        assertEquals("serviceCategory", cbMessage.getServiceCategory(),
                SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
        assertEquals("payload", cbMessage.getMessageBody(),
                "This is a test of the Commercial Mobile Alert System. This is only a test.");

        SmsCbCmasInfo cmasInfo = cbMessage.getCmasWarningInfo();
        assertNotNull("expected non-null for CMAS info", cmasInfo);
        assertEquals("category", cmasInfo.getCategory(), SmsCbCmasInfo.CMAS_CATEGORY_OTHER);
        assertEquals("responseType", cmasInfo.getResponseType(),
                SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE);
        assertEquals("severity", cmasInfo.getSeverity(), SmsCbCmasInfo.CMAS_SEVERITY_SEVERE);
        assertEquals("urgency", cmasInfo.getUrgency(), SmsCbCmasInfo.CMAS_URGENCY_EXPECTED);
        assertEquals("certainty", cmasInfo.getCertainty(), SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY);
    
public voidtestNonEmergencyBroadcast16bitUnicode()

        doTestNonEmergencyBroadcast(UserData.ENCODING_UNICODE_16);
    
public voidtestNonEmergencyBroadcast7bitAscii()

        doTestNonEmergencyBroadcast(UserData.ENCODING_7BIT_ASCII);
    
public voidtestNonEmergencyBroadcast7bitGsm()

        doTestNonEmergencyBroadcast(UserData.ENCODING_GSM_7BIT_ALPHABET);
    
public voidtestNonEmergencyBroadcastIs91Extended()

        // IS-91 doesn't support language or priority subparameters, max 14 chars text
        SmsMessage msg = createBroadcastSmsMessage(987, 654, -1, -1,
                UserData.ENCODING_IS91_EXTENDED_PROTOCOL, IS91_TEXT);

        SmsCbMessage cbMessage = msg.parseBroadcastSms();
        verifyCbValues(cbMessage);
        assertEquals(987, cbMessage.getServiceCategory());
        assertEquals(654, cbMessage.getSerialNumber());
        assertEquals(SmsCbMessage.MESSAGE_PRIORITY_NORMAL, cbMessage.getMessagePriority());
        assertEquals(null, cbMessage.getLanguageCode());
        assertEquals(IS91_TEXT, cbMessage.getMessageBody());
        assertEquals(false, cbMessage.isEmergencyMessage());
        assertEquals(false, cbMessage.isCmasMessage());
    
public voidtestRandomBearerStreamData()

        Random r = new Random(54321);
        for (int run = 0; run < 1000; run++) {
            int len = r.nextInt(140);
            byte[] data = new byte[len];
            for (int i = 0; i < len; i++) {
                data[i] = (byte) r.nextInt(256);
            }
            // Rlog.d("CdmaSmsCbTest", "trying random bearer data run " + run + " length " + len);
            try {
                int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
                Parcel p = createBroadcastParcel(category);
                SmsMessage msg = createMessageFromParcel(p, data);
                SmsCbMessage cbMessage = msg.parseBroadcastSms();
                // with random input, cbMessage will almost always be null (log when it isn't)
                if (cbMessage != null) {
                    Rlog.d("CdmaSmsCbTest", "success: " + cbMessage);
                }
            } catch (Exception e) {
                Rlog.d("CdmaSmsCbTest", "exception thrown", e);
                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
            }
        }
    
public voidtestRandomUserData()

        Random r = new Random(94040);
        for (int run = 0; run < 1000; run++) {
            int category = 0x0ff0 + r.nextInt(32);  // half CMAS, half non-CMAS
            Parcel p = createBroadcastParcel(category);
            int len = r.nextInt(140);
            // Rlog.d("CdmaSmsCbTest", "trying random user data run " + run + " length " + len);

            try {
                BitwiseOutputStream bos = createBearerDataStream(r.nextInt(65536), r.nextInt(4),
                        r.nextInt(256));

                bos.write(8, SUBPARAM_USER_DATA);
                bos.write(8, len);

                for (int i = 0; i < len; i++) {
                    bos.write(8, r.nextInt(256));
                }

                SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
                SmsCbMessage cbMessage = msg.parseBroadcastSms();
            } catch (Exception e) {
                Rlog.d("CdmaSmsCbTest", "exception thrown", e);
                fail("Exception in decoder at run " + run + " length " + len + ": " + e);
            }
        }
    
public voidtestServiceCategoryProgramDataAddCategory()


         
        Parcel p = createServiceCategoryProgramDataParcel();
        BitwiseOutputStream bos = createBearerDataStream(123, -1, -1);

        int categoryNameLength = CAT_EXTREME_THREAT.length();
        int subparamLengthBits = (53 + (categoryNameLength * 7));
        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;

        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
        bos.write(8, subparamLengthBytes);
        bos.write(5, UserData.ENCODING_7BIT_ASCII);

        bos.write(4, CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY);
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT >>> 8));
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT & 0xff));
        bos.write(8, BearerData.LANGUAGE_ENGLISH);
        bos.write(8, 100);  // max messages
        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT);

        bos.write(8, categoryNameLength);
        for (int i = 0; i < categoryNameLength; i++) {
            bos.write(7, CAT_EXTREME_THREAT.charAt(i));
        }
        bos.write(subparamPadBits, 0);

        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
        assertNotNull(msg);
        msg.parseSms();
        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
        assertNotNull(programDataList);
        assertEquals(1, programDataList.size());
        CdmaSmsCbProgramData programData = programDataList.get(0);
        assertEquals(CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY, programData.getOperation());
        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, programData.getCategory());
        assertEquals(CAT_EXTREME_THREAT, programData.getCategoryName());
        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
        assertEquals(100, programData.getMaxMessages());
        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_DEFAULT_ALERT, programData.getAlertOption());
    
public voidtestServiceCategoryProgramDataDeleteTwoCategories()

        Parcel p = createServiceCategoryProgramDataParcel();
        BitwiseOutputStream bos = createBearerDataStream(456, -1, -1);

        int category1NameLength = CAT_SEVERE_THREAT.length();
        int category2NameLength = CAT_AMBER_ALERTS.length();

        int subparamLengthBits = (101 + (category1NameLength * 7) + (category2NameLength * 7));
        int subparamLengthBytes = (subparamLengthBits + 7) / 8;
        int subparamPadBits = (subparamLengthBytes * 8) - subparamLengthBits;

        bos.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_DATA);
        bos.write(8, subparamLengthBytes);
        bos.write(5, UserData.ENCODING_7BIT_ASCII);

        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT >>> 8));
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT & 0xff));
        bos.write(8, BearerData.LANGUAGE_ENGLISH);
        bos.write(8, 0);  // max messages
        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);

        bos.write(8, category1NameLength);
        for (int i = 0; i < category1NameLength; i++) {
            bos.write(7, CAT_SEVERE_THREAT.charAt(i));
        }

        bos.write(4, CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY);
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY >>> 8));
        bos.write(8, (SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY & 0xff));
        bos.write(8, BearerData.LANGUAGE_ENGLISH);
        bos.write(8, 0);  // max messages
        bos.write(4, CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT);

        bos.write(8, category2NameLength);
        for (int i = 0; i < category2NameLength; i++) {
            bos.write(7, CAT_AMBER_ALERTS.charAt(i));
        }

        bos.write(subparamPadBits, 0);

        SmsMessage msg = createMessageFromParcel(p, bos.toByteArray());
        assertNotNull(msg);
        msg.parseSms();
        List<CdmaSmsCbProgramData> programDataList = msg.getSmsCbProgramData();
        assertNotNull(programDataList);
        assertEquals(2, programDataList.size());

        CdmaSmsCbProgramData programData = programDataList.get(0);
        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, programData.getCategory());
        assertEquals(CAT_SEVERE_THREAT, programData.getCategoryName());
        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
        assertEquals(0, programData.getMaxMessages());
        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());

        programData = programDataList.get(1);
        assertEquals(CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY, programData.getOperation());
        assertEquals(SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
                programData.getCategory());
        assertEquals(CAT_AMBER_ALERTS, programData.getCategoryName());
        assertEquals(BearerData.LANGUAGE_ENGLISH, programData.getLanguage());
        assertEquals(0, programData.getMaxMessages());
        assertEquals(CdmaSmsCbProgramData.ALERT_OPTION_NO_ALERT, programData.getAlertOption());
    
private static voidverifyCbValues(android.telephony.SmsCbMessage cbMessage)
Verify that the SmsCbMessage has the correct values for CDMA.

param
cbMessage the message to test

   // max length 14 chars

                         
         
        assertEquals(SmsCbMessage.MESSAGE_FORMAT_3GPP2, cbMessage.getMessageFormat());
        assertEquals(SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, cbMessage.getGeographicalScope());
        assertEquals(false, cbMessage.isEtwsMessage()); // ETWS on CDMA not currently supported