SmsMessage.java revision cbaa45bbf2cab852b6c9c3a887e9f803d4e857ea
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2008 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.os.SystemProperties; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.PhoneNumberUtils; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbLocation; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbMessage; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.cdma.CdmaSmsCbProgramData; 25ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Savilleimport android.telephony.Rlog; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsConstants; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsHeader; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.BearerData; 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.UserData; 38d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.BitwiseInputStream; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump; 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.BufferedOutputStream; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayInputStream; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayOutputStream; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.DataInputStream; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.DataOutputStream; 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.IOException; 48b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport java.util.ArrayList; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): these constants are disturbing... are they not just 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * different interpretations on one number? And if we did not have 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * terrible class name overlap, they would not need to be directly 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * imported like this. The class in this file could just as well be 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * named CdmaSmsMessage, could it not? 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): internally returning null in many places makes 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * debugging very hard (among many other reasons) and should be made 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * more meaningful (replaced with exceptions for example). Null 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * returns should only occur at the very outside of the module/class 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * scope. 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * A Short Message Service message. 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class SmsMessage extends SmsMessageBase { 71cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville static final String LOG_TAG = "SmsMessage"; 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static private final String LOGGABLE_TAG = "CDMA:SMS"; 73cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final boolean VDBG = false; 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte TELESERVICE_IDENTIFIER = 0x00; 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte SERVICE_CATEGORY = 0x01; 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte ORIGINATING_ADDRESS = 0x02; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte ORIGINATING_SUB_ADDRESS = 0x03; 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte DESTINATION_ADDRESS = 0x04; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte DESTINATION_SUB_ADDRESS = 0x05; 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte BEARER_REPLY_OPTION = 0x06; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte CAUSE_CODES = 0x07; 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte BEARER_DATA = 0x08; 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Status of a previously submitted SMS. 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This field applies to SMS Delivery Acknowledge messages. 0 indicates success; 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0. 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values. 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int status; 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Specifies if a return of an acknowledgment is requested for send SMS */ 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int RETURN_NO_ACK = 0; 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int RETURN_ACK = 1; 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private SmsEnvelope mEnvelope; 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private BearerData mBearerData; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static class SubmitPdu extends SubmitPduBase { 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create an SmsMessage from a raw PDU. 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: In CDMA the PDU is just a byte representation of the received Sms. 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage createFromPdu(byte[] pdu) { 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.parsePdu(pdu); 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 114ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp. 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: Only primitive fields are set. 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage newFromParcel(Parcel p) { 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note: Parcel.readByte actually reads one Int and masks to byte 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress(); 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data; 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte count; 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int countInt; 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int addressDigitMode; 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //currently not supported by the modem-lib: env.mMessageType 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = p.readInt(); //p_cur->uTeleserviceID 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 != p.readByte()) { //p_cur->bIsServicePresent 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST; 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville else { 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) { 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // assume type ACK 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE; 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = p.readInt(); //p_cur->uServicecategory 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // address 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addressDigitMode = p.readInt(); 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = (byte) (0xFF & addressDigitMode); //p_cur->sAddress.digit_mode 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = p.readInt(); //p_cur->sAddress.number_type 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = p.readByte(); //p_cur->sAddress.number_of_digits 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = count; 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[count]; 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //p_cur->sAddress.digits[digitCount] 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index=0; index < count; index++) { 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 bit 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = msg.convertDtmfToAscii(data[index]); 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = data; 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = p.readByte(); // p_cur->sSubAddress.number_of_digits 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (count < 0) { 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = 0; 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // p_cur->sSubAddress.digits[digitCount] : 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[count]; 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < count; ++index) { 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.origBytes = data; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* currently not supported by the modem-lib: 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // bearer data 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville countInt = p.readInt(); //p_cur->uBearerDataLen 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (countInt < 0) { 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville countInt = 0; 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[countInt]; 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index=0; index < countInt; index++) { 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // BD gets further decoded when accessed in SMSDispatcher 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = data; 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the the filled objects to the SMS 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origSubaddress = subaddr; 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.originatingAddress = addr; 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.mEnvelope = env; 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // create byte stream representation for transportation through the layers. 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.createPdu(); 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create an SmsMessage from an SMS EF record. 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param index Index of SMS record. This should be index in ArrayList 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1. 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data Record data. 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return An SmsMessage representing the record. 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage createFromEfRecord(int index, byte[] data) { 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.indexOnIcc = index; 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT, 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // or STORED_UNSENT 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See 3GPP2 C.S0023 3.4.27 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((data[0] & 1) == 0) { 241ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record"); 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.statusOnIcc = data[0] & 0x07; 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Second byte is the MSG_LEN, length of the message 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See 3GPP2 C.S0023 3.4.27 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int size = data[1]; 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note: Data may include trailing FF's. That's OK; message 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // should still parse correctly. 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] pdu = new byte[size]; 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(data, 2, pdu, 0, size); 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the message has to be parsed before it can be displayed 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // see gsm.SmsMessage 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.parsePduFromEfRecord(pdu); 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 260ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static int getTPLayerLengthForPDU(String pdu) { 270ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode."); 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): why do getSubmitPdu methods take an scAddr input 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and do nothing with it? GSM allows us to specify a SC (eg, 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * when responding to an SMS that explicitly requests the response 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is sent to a specific SC), or pass null to use the default 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * value. Is there no similar notion in CDMA? Or do we just not 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * have it hooked up? 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a destination address and a message 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr Service Centre address. Null means use default. 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr Address of the recipient. 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param message String representation of the message payload. 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param statusReportRequested Indicates whether a report is requested for this message. 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param smsHeader Array containing the data for the User Data Header, preceded 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * by the Element Identifiers. 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean statusReportRequested, SmsHeader smsHeader) { 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): Do we really want silent failure like this? 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Would it not be much more reasonable to make sure we don't 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * call this function if we really want nothing done? 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (message == null || destAddr == null) { 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData uData = new UserData(); 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.payloadStr = message; 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.userDataHeader = smsHeader; 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a data message to a destination address and port. 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr Service Centre address. null == use default 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address of the destination for the message 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destPort the port to deliver the message to at the 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * destination 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data the data for the message 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort, 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data, boolean statusReportRequested) { 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): this is not a general-purpose SMS creation 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * method, but rather something specialized to messages 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * containing OCTET encoded (meaning non-human-readable) user 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * data. The name should reflect that, and not just overload. 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.destPort = destPort; 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.origPort = 0; 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.areEightBits = false; 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsHeader smsHeader = new SmsHeader(); 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsHeader.portAddrs = portAddrs; 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData uData = new UserData(); 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.userDataHeader = smsHeader; 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncoding = UserData.ENCODING_OCTET; 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncodingSet = true; 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.payload = data; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a data message to a destination address & port 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address of the destination for the message 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param userData the data for the message 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param statusReportRequested Indicates whether a report is requested for this message. 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String destAddr, UserData userData, 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean statusReportRequested) { 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, userData); 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 372cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getProtocolIdentifier() { 374ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode."); 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (3GPP TS 23.040): "no interworking, but SME to SME protocol": 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 382cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isReplace() { 384ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isReplace: is not supported in CDMA mode."); 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 392cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isCphsMwiMessage() { 394ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode."); 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 401cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMWIClearMessage() { 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && (mBearerData.numberOfMessages == 0)); 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 409cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMWISetMessage() { 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && (mBearerData.numberOfMessages > 0)); 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 417cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMwiDontStore() { 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (mBearerData.numberOfMessages > 0) && 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (mBearerData.userData == null)); 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the status for a previously submitted message. 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * For not interfering with status codes from GSM, this status code is 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * shifted to the bits 31-16. 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 429cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getStatus() { 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (status << 16); 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Return true iff the bearer data message type is DELIVERY_ACK. */ 435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isStatusReportMessage() { 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK); 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 443cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isReplyPathPresent() { 445ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode."); 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Calculate the number of septets needed to encode the message. 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param messageBody the message to encode 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param use7bitOnly ignore (but still count) illegal characters if true 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return TextEncodingDetails 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static TextEncodingDetails calculateLength(CharSequence messageBody, 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean use7bitOnly) { 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly); 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the teleservice type of the message. 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the teleservice: 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET}, 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT}, 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT}, 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN}, 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP} 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ int getTeleService() { 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mEnvelope.teleService; 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the message type of the message. 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the message type: 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT}, 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST}, 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ int getMessageType() { 48234661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs. 48334661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby // Use the service category parameter to detect CMAS and other cell broadcast messages. 48434661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby if (mEnvelope.serviceCategory != 0) { 48534661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby return SmsEnvelope.MESSAGE_TYPE_BROADCAST; 48634661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby } else { 48734661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 48834661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby } 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes pdu to an empty SMS object. 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * In the CDMA case the pdu is just an internal byte stream representation 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * of the SMS Java-object. 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @see #createPdu() 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void parsePdu(byte[] pdu) { 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataInputStream dis = new DataInputStream(bais); 500e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga int length; 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bearerDataLength; 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = dis.readInt(); 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = dis.readInt(); 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = dis.readInt(); 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = dis.readByte(); 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = dis.readByte(); 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = dis.readByte(); 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = dis.readByte(); 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 515e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga length = dis.readUnsignedByte(); 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = length; 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = new byte[length]; 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(addr.origBytes, 0, length); // digits 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply = dis.readInt(); 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // CauseCode values: 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo = dis.readByte(); 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass = dis.readByte(); 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode = dis.readByte(); 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //encoded BearerData: 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerDataLength = dis.readInt(); 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = new byte[bearerDataLength]; 5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(env.bearerData, 0, bearerDataLength); 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.close(); 5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception ex) { 532ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex); 5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the filled objects to this SMS 5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville originatingAddress = addr; 5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope = env; 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = pdu; 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseSms(); 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void parsePduFromEfRecord(byte[] pdu) { 5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataInputStream dis = new DataInputStream(bais); 5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress(); 5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = dis.readByte(); 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (dis.available() > 0) { 5580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int parameterId = dis.readByte(); 559e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga int parameterLen = dis.readUnsignedByte(); 5600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] parameterData = new byte[parameterLen]; 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (parameterId) { 5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case TELESERVICE_IDENTIFIER: 5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 16 bit parameter that identifies which upper layer 5660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * service access point is sending or should receive 5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this message 5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = dis.readUnsignedShort(); 570ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "teleservice = " + env.teleService); 5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SERVICE_CATEGORY: 5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 16 bit parameter that identifies type of service as 5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * in 3GPP2 C.S0015-0 Table 3.4.3.2-1 5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = dis.readUnsignedShort(); 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case ORIGINATING_ADDRESS: 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DESTINATION_ADDRESS: 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream addrBis = new BitwiseInputStream(parameterData); 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = addrBis.read(1); 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = addrBis.read(1); 5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numberType = 0; 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville numberType = addrBis.read(3); 5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = numberType; 5890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) 5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = addrBis.read(4); 5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = addrBis.read(8); 5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data = new byte[addr.numberOfDigits]; 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte b = 0x00; 5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 6000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */ 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < addr.numberOfDigits; index++) { 6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xF & addrBis.read(4)); 6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // bit 6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = convertDtmfToAscii(b); 6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) { 6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < addr.numberOfDigits; index++) { 6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xFF & addrBis.read(8)); 6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = b; 6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { 6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (numberType == 2) 616ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "TODO: Originating Addr is email id"); 6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville else 618ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, 6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "TODO: Originating Addr is data network address"); 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 621ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "Originating Addr is of incorrect type"); 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 624ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "Incorrect Digit mode"); 6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = data; 627ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "Originating Addr=" + addr.toString()); 6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case ORIGINATING_SUB_ADDRESS: 6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DESTINATION_SUB_ADDRESS: 6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData); 6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.type = subAddrBis.read(3); 6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.odd = subAddrBis.readByteArray(1)[0]; 6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int subAddrLen = subAddrBis.read(8); 6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] subdata = new byte[subAddrLen]; 6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < subAddrLen; index++) { 6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xFF & subAddrBis.read(4)); 6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 bit 6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subdata[index] = convertDtmfToAscii(b); 6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.origBytes = subdata; 6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case BEARER_REPLY_OPTION: 6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData); 6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply = replyOptBis.read(6); 6480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CAUSE_CODES: 6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream ccBis = new BitwiseInputStream(parameterData); 6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo = ccBis.readByteArray(6)[0]; 6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass = ccBis.readByteArray(2)[0]; 6540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (env.errorClass != 0x00) 6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode = ccBis.readByteArray(8)[0]; 6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case BEARER_DATA: 6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = parameterData; 6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new Exception("unsupported parameterId (" + parameterId + ")"); 6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bais.close(); 6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.close(); 6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception ex) { 668ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex); 6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the filled objects to this SMS 6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville originatingAddress = addr; 6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origSubaddress = subAddr; 6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope = env; 6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = pdu; 6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseSms(); 6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parses a SMS message from its BearerData stream. (mobile-terminated only) 6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void parseSms() { 6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // It contains only an 8-bit number with the number of messages waiting 6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) { 6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData = new BearerData(); 6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mEnvelope.bearerData != null) { 6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0]; 6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 692cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) { 693ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "parseSms: get MWI " + 6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Integer.toString(mBearerData.numberOfMessages)); 6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData = BearerData.decode(mEnvelope.bearerData); 699ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 700ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT raw BearerData = '" + 7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville HexDump.toHexString(mEnvelope.bearerData) + "'"); 702ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData); 7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville messageRef = mBearerData.messageId; 7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.userData != null) { 7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville userData = mBearerData.userData.payload; 7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville userDataHeader = mBearerData.userData.userDataHeader; 7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville messageBody = mBearerData.userData.payloadStr; 7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (originatingAddress != null) { 7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville originatingAddress.address = new String(originatingAddress.origBytes); 713cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: " 7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + originatingAddress.address); 7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.msgCenterTimeStamp != null) { 7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); 7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 721cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); 7220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1) 7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) { 7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The BearerData MsgStatus subparameter should only be 7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // included for DELIVERY_ACK messages. If it occurred for 7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // other messages, it would be unclear what the status 7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // being reported refers to. The MsgStatus subparameter 7290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // is primarily useful to indicate error conditions -- a 7300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // message without this subparameter is assumed to 7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // indicate successful delivery (status == 0). 7320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (! mBearerData.messageStatusSet) { 733ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" + 7340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (userData == null ? "also missing" : "does have") + 7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " userData)."); 7360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status = 0; 7370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status = mBearerData.errorClass << 8; 7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status |= mBearerData.messageStatus; 7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { 7420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); 7430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (messageBody != null) { 746cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) Rlog.v(LOG_TAG, "SMS message body: '" + messageBody + "'"); 7470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseMessageBody(); 748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville } else if ((userData != null) && VDBG) { 749ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(userData) + "'"); 7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parses a broadcast SMS, possibly containing a CMAS alert. 7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 7560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbMessage parseBroadcastSms() { 7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory); 7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (bData == null) { 759ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "BearerData.decode() returned null"); 7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 763ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 764ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData)); 7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); 7680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbLocation location = new SmsCbLocation(plmn); 7690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2, 7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location, 7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr, 7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bData.priority, null, bData.cmasWarningInfo); 7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 7800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsConstants.MessageClass getMessageClass() { 7810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) { 7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsConstants.MessageClass.CLASS_0; 7830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsConstants.MessageClass.UNKNOWN; 7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Calculate the next message id, starting at 1 and iteratively 7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * incrementing within the range 1..65535 remembering the state 7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * via a persistent system property. (See C.S0015-B, v2.0, 7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4.3.1.5) Since this routine is expected to be accessed via via 7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * binder-call, and hence should be thread-safe, it has been 7940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * synchronized. 7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 796b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby synchronized static int getNextMessageId() { 7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Testing and dialog with partners has indicated that 7980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // msgId==0 is (sometimes?) treated specially by lower levels. 7990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Specifically, the ID is not preserved for delivery ACKs. 8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Hence, avoid 0 -- constraining the range to 1..65535. 8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1); 8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1); 8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId); 804ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 805ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId); 806ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "readback gets " + 8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID)); 8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msgId; 8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Creates BearerData and Envelope from parameters for a Submit SMS. 8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte stream for SubmitPdu. 8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested, 8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData userData) { 8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): give this function a more meaningful name. 8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): Make returning null from the getSubmitPdu 8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * variations meaningful -- clean up the error feedback 8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * mechanism, and avoid null pointer exceptions. 8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * North America Plus Code : 8310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Convert + code to 011 and dial out for international SMS 8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress destAddr = CdmaSmsAddress.parse( 8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PhoneNumberUtils.cdmaCheckAndProcessPlusCode(destAddrStr)); 8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (destAddr == null) return null; 8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BearerData bearerData = new BearerData(); 8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; 8390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.messageId = getNextMessageId(); 8410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.deliveryAckReq = statusReportRequested; 8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.userAckReq = false; 8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.readAckReq = false; 8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.reportReq = false; 8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.userData = userData; 8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] encodedBearerData = BearerData.encode(bearerData); 850ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 851ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData); 852ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'"); 8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (encodedBearerData == null) return null; 8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int teleservice = bearerData.hasUserDataHeader ? 8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; 8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope envelope = new SmsEnvelope(); 8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.teleService = teleservice; 8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.destAddress = destAddr; 8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.bearerReply = RETURN_ACK; 8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.bearerData = encodedBearerData; 8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): envelope looks to be a pointless class, get 8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * rid of it. Also -- most of the envelope fields set here 8690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * are ignored, why? 8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): reference a spec and get rid of the ugly comments 8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataOutputStream dos = new DataOutputStream(baos); 8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(envelope.teleService); 8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(0); //servicePresent 8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(0); //serviceCategory 8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.digitMode); 8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberMode); 8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.ton); // number_type 8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberPlan); 8850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberOfDigits); 8860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits 8870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Subaddress is not supported. 8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddressType 8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddr_odd 8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddr_nbr_of_digits 8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(encodedBearerData.length); 8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(encodedBearerData, 0, encodedBearerData.length); 8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.close(); 8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SubmitPdu pdu = new SubmitPdu(); 8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu.encodedMessage = baos.toByteArray(); 8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu.encodedScAddress = null; 8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return pdu; 8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch(IOException ex) { 900ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "creating SubmitPdu failed: " + ex); 9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Creates byte array (pseudo pdu) from SMS object. 9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: Do not call this method more than once per object! 9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void createPdu() { 9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = mEnvelope; 9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = env.origAddress; 9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos)); 9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.messageType); 9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.teleService); 9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.serviceCategory); 9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.digitMode); 9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberMode); 9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.ton); 9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberPlan); 9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberOfDigits); 9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(addr.origBytes, 0, addr.origBytes.length); // digits 9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.bearerReply); 9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // CauseCode values: 9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.replySeqNo); 9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.errorClass); 9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.causeCode); 9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //encoded BearerData: 9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.bearerData.length); 9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(env.bearerData, 0, env.bearerData.length); 9350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.close(); 9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup) -- The mPdu field is managed in 9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a fragile manner, and it would be much nicer if 9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * accessing the serialized representation used a less 9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * fragile mechanism. Maybe the getPdu method could 9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * generate a representation if there was not yet one? 9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = baos.toByteArray(); 9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (IOException ex) { 947ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex); 9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character 9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private byte convertDtmfToAscii(byte dtmfDigit) { 9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte asciiDigit; 9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (dtmfDigit) { 9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 0: asciiDigit = 68; break; // 'D' 9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 1: asciiDigit = 49; break; // '1' 9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 2: asciiDigit = 50; break; // '2' 9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 3: asciiDigit = 51; break; // '3' 9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 4: asciiDigit = 52; break; // '4' 9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 5: asciiDigit = 53; break; // '5' 9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 6: asciiDigit = 54; break; // '6' 9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 7: asciiDigit = 55; break; // '7' 9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 8: asciiDigit = 56; break; // '8' 9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 9: asciiDigit = 57; break; // '9' 9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 10: asciiDigit = 48; break; // '0' 9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 11: asciiDigit = 42; break; // '*' 9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 12: asciiDigit = 35; break; // '#' 9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 13: asciiDigit = 65; break; // 'A' 9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 14: asciiDigit = 66; break; // 'B' 9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 15: asciiDigit = 67; break; // 'C' 9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville asciiDigit = 32; // Invalid DTMF code 9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return asciiDigit; 9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** This function shall be called to get the number of voicemails. 9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ int getNumOfVoicemails() { 9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mBearerData.numberOfMessages; 9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns a byte array that can be use to uniquely identify a received SMS message. 9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * C.S0015-B 4.3.1.6 Unique Message Identification. 9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte array uniquely identifying the message. 9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ byte[] getIncomingSmsFingerprint() { 9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream output = new ByteArrayOutputStream(); 9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.teleService); 10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length); 10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length); 10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.origSubaddress.origBytes, 0, 10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope.origSubaddress.origBytes.length); 10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return output.toByteArray(); 10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the list of service category program data, if present. 10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a list of CdmaSmsCbProgramData objects, or null if not present 10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1012b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby ArrayList<CdmaSmsCbProgramData> getSmsCbProgramData() { 10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mBearerData.serviceCategoryProgramData; 10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 1016