SmsMessage.java revision 8b53bb26569395511e3dbd5f94bda74ea6b9e37c
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; 278b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Yingimport android.text.TextUtils; 288b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Yingimport android.content.res.Resources; 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsConstants; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsHeader; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.BearerData; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress; 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.UserData; 40d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils; 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.BitwiseInputStream; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.util.HexDump; 438b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Yingimport com.android.internal.telephony.Sms7BitEncodingTranslator; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.BufferedOutputStream; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayInputStream; 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayOutputStream; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.DataInputStream; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.DataOutputStream; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.IOException; 51b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport java.util.ArrayList; 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): these constants are disturbing... are they not just 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * different interpretations on one number? And if we did not have 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * terrible class name overlap, they would not need to be directly 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * imported like this. The class in this file could just as well be 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * named CdmaSmsMessage, could it not? 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): internally returning null in many places makes 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * debugging very hard (among many other reasons) and should be made 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * more meaningful (replaced with exceptions for example). Null 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * returns should only occur at the very outside of the module/class 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * scope. 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * A Short Message Service message. 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class SmsMessage extends SmsMessageBase { 74cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville static final String LOG_TAG = "SmsMessage"; 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static private final String LOGGABLE_TAG = "CDMA:SMS"; 76cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final boolean VDBG = false; 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte TELESERVICE_IDENTIFIER = 0x00; 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte SERVICE_CATEGORY = 0x01; 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte ORIGINATING_ADDRESS = 0x02; 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte ORIGINATING_SUB_ADDRESS = 0x03; 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte DESTINATION_ADDRESS = 0x04; 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte DESTINATION_SUB_ADDRESS = 0x05; 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte BEARER_REPLY_OPTION = 0x06; 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte CAUSE_CODES = 0x07; 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final static byte BEARER_DATA = 0x08; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Status of a previously submitted SMS. 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * This field applies to SMS Delivery Acknowledge messages. 0 indicates success; 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0. 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values. 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int status; 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Specifies if a return of an acknowledgment is requested for send SMS */ 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int RETURN_NO_ACK = 0; 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static final int RETURN_ACK = 1; 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private SmsEnvelope mEnvelope; 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private BearerData mBearerData; 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static class SubmitPdu extends SubmitPduBase { 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create an SmsMessage from a raw PDU. 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: In CDMA the PDU is just a byte representation of the received Sms. 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage createFromPdu(byte[] pdu) { 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.parsePdu(pdu); 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 117ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 1191260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } catch (OutOfMemoryError e) { 1201260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa Log.e(LOG_TAG, "SMS PDU parsing failed with out of memory: ", e); 1211260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa return null; 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp. 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: Only primitive fields are set. 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage newFromParcel(Parcel p) { 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note: Parcel.readByte actually reads one Int and masks to byte 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress(); 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data; 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte count; 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int countInt; 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int addressDigitMode; 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //currently not supported by the modem-lib: env.mMessageType 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = p.readInt(); //p_cur->uTeleserviceID 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (0 != p.readByte()) { //p_cur->bIsServicePresent 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST; 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville else { 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) { 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // assume type ACK 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE; 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = p.readInt(); //p_cur->uServicecategory 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // address 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addressDigitMode = p.readInt(); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = (byte) (0xFF & addressDigitMode); //p_cur->sAddress.digit_mode 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = p.readInt(); //p_cur->sAddress.number_type 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = p.readByte(); //p_cur->sAddress.number_of_digits 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = count; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[count]; 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //p_cur->sAddress.digits[digitCount] 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index=0; index < count; index++) { 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 bit 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = msg.convertDtmfToAscii(data[index]); 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = data; 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = p.readByte(); // p_cur->sSubAddress.number_of_digits 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (count < 0) { 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville count = 0; 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // p_cur->sSubAddress.digits[digitCount] : 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[count]; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < count; ++index) { 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subaddr.origBytes = data; 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* currently not supported by the modem-lib: 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // bearer data 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville countInt = p.readInt(); //p_cur->uBearerDataLen 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (countInt < 0) { 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville countInt = 0; 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data = new byte[countInt]; 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index=0; index < countInt; index++) { 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = p.readByte(); 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // BD gets further decoded when accessed in SMSDispatcher 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = data; 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the the filled objects to the SMS 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origSubaddress = subaddr; 21822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville msg.mOriginatingAddress = addr; 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.mEnvelope = env; 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // create byte stream representation for transportation through the layers. 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.createPdu(); 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Create an SmsMessage from an SMS EF record. 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param index Index of SMS record. This should be index in ArrayList 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1. 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data Record data. 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return An SmsMessage representing the record. 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SmsMessage createFromEfRecord(int index, byte[] data) { 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage msg = new SmsMessage(); 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 24122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville msg.mIndexOnIcc = index; 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT, 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // or STORED_UNSENT 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See 3GPP2 C.S0023 3.4.27 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((data[0] & 1) == 0) { 247ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record"); 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 25022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville msg.mStatusOnIcc = data[0] & 0x07; 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Second byte is the MSG_LEN, length of the message 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See 3GPP2 C.S0023 3.4.27 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int size = data[1]; 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Note: Data may include trailing FF's. That's OK; message 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // should still parse correctly. 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] pdu = new byte[size]; 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(data, 2, pdu, 0, size); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // the message has to be parsed before it can be displayed 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // see gsm.SmsMessage 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville msg.parsePduFromEfRecord(pdu); 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msg; 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (RuntimeException ex) { 266ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static int getTPLayerLengthForPDU(String pdu) { 276ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode."); 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): why do getSubmitPdu methods take an scAddr input 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * and do nothing with it? GSM allows us to specify a SC (eg, 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * when responding to an SMS that explicitly requests the response 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is sent to a specific SC), or pass null to use the default 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * value. Is there no similar notion in CDMA? Or do we just not 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * have it hooked up? 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a destination address and a message 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr Service Centre address. Null means use default. 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr Address of the recipient. 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param message String representation of the message payload. 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param statusReportRequested Indicates whether a report is requested for this message. 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param smsHeader Array containing the data for the User Data Header, preceded 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * by the Element Identifiers. 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean statusReportRequested, SmsHeader smsHeader) { 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): Do we really want silent failure like this? 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Would it not be much more reasonable to make sure we don't 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * call this function if we really want nothing done? 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (message == null || destAddr == null) { 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData uData = new UserData(); 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.payloadStr = message; 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.userDataHeader = smsHeader; 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a data message to a destination address and port. 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param scAddr Service Centre address. null == use default 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address of the destination for the message 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destPort the port to deliver the message to at the 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * destination 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param data the data for the message 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort, 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data, boolean statusReportRequested) { 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): this is not a general-purpose SMS creation 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * method, but rather something specialized to messages 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * containing OCTET encoded (meaning non-human-readable) user 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * data. The name should reflect that, and not just overload. 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.destPort = destPort; 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.origPort = 0; 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville portAddrs.areEightBits = false; 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsHeader smsHeader = new SmsHeader(); 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville smsHeader.portAddrs = portAddrs; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData uData = new UserData(); 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.userDataHeader = smsHeader; 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncoding = UserData.ENCODING_OCTET; 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncodingSet = true; 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.payload = data; 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Get an SMS-SUBMIT PDU for a data message to a destination address & port 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param destAddr the address of the destination for the message 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param userData the data for the message 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param statusReportRequested Indicates whether a report is requested for this message. 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * address, if applicable, and the encoded message. 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns null on encode error. 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static SubmitPdu getSubmitPdu(String destAddr, UserData userData, 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean statusReportRequested) { 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return privateGetSubmitPdu(destAddr, statusReportRequested, userData); 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 378cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getProtocolIdentifier() { 380ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode."); 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (3GPP TS 23.040): "no interworking, but SME to SME protocol": 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 388cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isReplace() { 390ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isReplace: is not supported in CDMA mode."); 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 398cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isCphsMwiMessage() { 400ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode."); 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 407cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMWIClearMessage() { 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && (mBearerData.numberOfMessages == 0)); 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 415cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMWISetMessage() { 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && (mBearerData.numberOfMessages > 0)); 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 423cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isMwiDontStore() { 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ((mBearerData != null) && 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (mBearerData.numberOfMessages > 0) && 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (mBearerData.userData == null)); 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the status for a previously submitted message. 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * For not interfering with status codes from GSM, this status code is 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * shifted to the bits 31-16. 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 435cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getStatus() { 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (status << 16); 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Return true iff the bearer data message type is DELIVERY_ACK. */ 441cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isStatusReportMessage() { 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK); 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 449cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville @Override 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isReplyPathPresent() { 451ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode."); 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Calculate the number of septets needed to encode the message. 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param messageBody the message to encode 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param use7bitOnly ignore (but still count) illegal characters if true 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return TextEncodingDetails 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public static TextEncodingDetails calculateLength(CharSequence messageBody, 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean use7bitOnly) { 4648b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying CharSequence newMsgBody = null; 4658b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying Resources r = Resources.getSystem(); 4668b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) { 4678b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying newMsgBody = Sms7BitEncodingTranslator.translate(messageBody); 4688b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying } 4698b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying if (TextUtils.isEmpty(newMsgBody)) { 4708b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying newMsgBody = messageBody; 4718b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying } 4728b53bb26569395511e3dbd5f94bda74ea6b9e37cXia Ying return BearerData.calcTextEncodingDetails(newMsgBody, use7bitOnly); 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the teleservice type of the message. 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the teleservice: 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET}, 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT}, 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT}, 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN}, 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP} 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ int getTeleService() { 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mEnvelope.teleService; 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the message type of the message. 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return the message type: 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT}, 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST}, 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ int getMessageType() { 49634661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs. 49734661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby // Use the service category parameter to detect CMAS and other cell broadcast messages. 49834661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby if (mEnvelope.serviceCategory != 0) { 49934661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby return SmsEnvelope.MESSAGE_TYPE_BROADCAST; 50034661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby } else { 50134661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 50234661b1e9381d56b168777e3f18f6f9f2ad305c1Jake Hamby } 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes pdu to an empty SMS object. 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * In the CDMA case the pdu is just an internal byte stream representation 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * of the SMS Java-object. 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @see #createPdu() 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void parsePdu(byte[] pdu) { 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataInputStream dis = new DataInputStream(bais); 514e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga int length; 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int bearerDataLength; 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = dis.readInt(); 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = dis.readInt(); 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = dis.readInt(); 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = dis.readByte(); 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = dis.readByte(); 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = dis.readByte(); 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = dis.readByte(); 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 529e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga length = dis.readUnsignedByte(); 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = length; 5311260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa 5321260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // sanity check on the length 5331260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (length > pdu.length) { 5341260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa throw new RuntimeException( 5351260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa "createFromPdu: Invalid pdu, addr.numberOfDigits " + length 5361260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa + " > pdu len " + pdu.length); 5371260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = new byte[length]; 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(addr.origBytes, 0, length); // digits 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply = dis.readInt(); 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // CauseCode values: 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo = dis.readByte(); 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass = dis.readByte(); 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode = dis.readByte(); 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //encoded BearerData: 5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerDataLength = dis.readInt(); 5491260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa // sanity check on the length 5501260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa if (bearerDataLength > pdu.length) { 5511260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa throw new RuntimeException( 5521260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa "createFromPdu: Invalid pdu, bearerDataLength " + bearerDataLength 5531260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa + " > pdu len " + pdu.length); 5541260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = new byte[bearerDataLength]; 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(env.bearerData, 0, bearerDataLength); 5570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.close(); 5581260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa } catch (IOException ex) { 5591260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa throw new RuntimeException( 5601260f1c6c909f2940989b72afe1b91fd83845eaaSukanya Rajkhowa "createFromPdu: conversion from byte array to object failed: " + ex, ex); 5610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception ex) { 562ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex); 5630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the filled objects to this SMS 56622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mOriginatingAddress = addr; 5670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 5680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope = env; 5690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = pdu; 5700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseSms(); 5720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 5750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0 5760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void parsePduFromEfRecord(byte[] pdu) { 5780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 5790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataInputStream dis = new DataInputStream(bais); 5800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = new SmsEnvelope(); 5810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 5820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress(); 5830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 5850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.messageType = dis.readByte(); 5860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (dis.available() > 0) { 5880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int parameterId = dis.readByte(); 589e72ec3f4031a24982d402bb35a7d17dc1868958dkyunga int parameterLen = dis.readUnsignedByte(); 5900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] parameterData = new byte[parameterLen]; 5910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (parameterId) { 5930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case TELESERVICE_IDENTIFIER: 5940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 5950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 16 bit parameter that identifies which upper layer 5960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * service access point is sending or should receive 5970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * this message 5980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 5990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.teleService = dis.readUnsignedShort(); 600ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "teleservice = " + env.teleService); 6010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case SERVICE_CATEGORY: 6030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* 6040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 16 bit parameter that identifies type of service as 6050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * in 3GPP2 C.S0015-0 Table 3.4.3.2-1 6060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 6070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.serviceCategory = dis.readUnsignedShort(); 6080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case ORIGINATING_ADDRESS: 6100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DESTINATION_ADDRESS: 6110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream addrBis = new BitwiseInputStream(parameterData); 6130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.digitMode = addrBis.read(1); 6140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberMode = addrBis.read(1); 6150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int numberType = 0; 6160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 6170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville numberType = addrBis.read(3); 6180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.ton = numberType; 6190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) 6210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberPlan = addrBis.read(4); 6220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.numberOfDigits = addrBis.read(8); 6250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data = new byte[addr.numberOfDigits]; 6270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte b = 0x00; 6280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 6300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */ 6310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < addr.numberOfDigits; index++) { 6320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xF & addrBis.read(4)); 6330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 6340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // bit 6350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = convertDtmfToAscii(b); 6360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 6380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) { 6390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < addr.numberOfDigits; index++) { 6400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xFF & addrBis.read(8)); 6410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville data[index] = b; 6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 6440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { 6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (numberType == 2) 646ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "TODO: Originating Addr is email id"); 6470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville else 648ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, 6490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "TODO: Originating Addr is data network address"); 6500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 651ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "Originating Addr is of incorrect type"); 6520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 654ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "Incorrect Digit mode"); 6550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville addr.origBytes = data; 657ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.i(LOG_TAG, "Originating Addr=" + addr.toString()); 6580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case ORIGINATING_SUB_ADDRESS: 6600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case DESTINATION_SUB_ADDRESS: 6610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData); 6630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.type = subAddrBis.read(3); 6640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.odd = subAddrBis.readByteArray(1)[0]; 6650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int subAddrLen = subAddrBis.read(8); 6660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] subdata = new byte[subAddrLen]; 6670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int index = 0; index < subAddrLen; index++) { 6680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville b = (byte) (0xFF & subAddrBis.read(4)); 6690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // convert the value if it is 4-bit DTMF to 8 bit 6700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subdata[index] = convertDtmfToAscii(b); 6710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville subAddr.origBytes = subdata; 6730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case BEARER_REPLY_OPTION: 6750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData); 6770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerReply = replyOptBis.read(6); 6780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case CAUSE_CODES: 6800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BitwiseInputStream ccBis = new BitwiseInputStream(parameterData); 6820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.replySeqNo = ccBis.readByteArray(6)[0]; 6830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.errorClass = ccBis.readByteArray(2)[0]; 6840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (env.errorClass != 0x00) 6850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.causeCode = ccBis.readByteArray(8)[0]; 6860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case BEARER_DATA: 6880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.read(parameterData, 0, parameterLen); 6890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.bearerData = parameterData; 6900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 6910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 6920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new Exception("unsupported parameterId (" + parameterId + ")"); 6930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 6950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bais.close(); 6960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dis.close(); 6970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (Exception ex) { 698ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex); 6990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // link the filled objects to this SMS 70222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mOriginatingAddress = addr; 7030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origAddress = addr; 7040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville env.origSubaddress = subAddr; 7050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope = env; 7060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = pdu; 7070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseSms(); 7090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 7120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parses a SMS message from its BearerData stream. (mobile-terminated only) 7130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 7140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void parseSms() { 7150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 7160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // It contains only an 8-bit number with the number of messages waiting 7170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) { 7180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData = new BearerData(); 7190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mEnvelope.bearerData != null) { 7200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0]; 7210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 722cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) { 723ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "parseSms: get MWI " + 7240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Integer.toString(mBearerData.numberOfMessages)); 7250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 7270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mBearerData = BearerData.decode(mEnvelope.bearerData); 729ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 730ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT raw BearerData = '" + 7310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville HexDump.toHexString(mEnvelope.bearerData) + "'"); 732ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData); 7330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 73422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessageRef = mBearerData.messageId; 7350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.userData != null) { 73622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mUserData = mBearerData.userData.payload; 73722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mUserDataHeader = mBearerData.userData.userDataHeader; 73822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mMessageBody = mBearerData.userData.payloadStr; 7390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 74122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mOriginatingAddress != null) { 74222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mOriginatingAddress.address = new String(mOriginatingAddress.origBytes); 74304187ec4d9cdef64cc1257815fa9e44e37202a86Sudheer Reddy Yampalla if (mOriginatingAddress.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) { 74404187ec4d9cdef64cc1257815fa9e44e37202a86Sudheer Reddy Yampalla if (mOriginatingAddress.address.charAt(0) != '+') { 74504187ec4d9cdef64cc1257815fa9e44e37202a86Sudheer Reddy Yampalla mOriginatingAddress.address = "+" + mOriginatingAddress.address; 74604187ec4d9cdef64cc1257815fa9e44e37202a86Sudheer Reddy Yampalla } 74704187ec4d9cdef64cc1257815fa9e44e37202a86Sudheer Reddy Yampalla } 748cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: " 74922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville + mOriginatingAddress.address); 7500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.msgCenterTimeStamp != null) { 75322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); 7540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 75622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis); 7570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1) 7590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) { 7600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // The BearerData MsgStatus subparameter should only be 7610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // included for DELIVERY_ACK messages. If it occurred for 7620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // other messages, it would be unclear what the status 7630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // being reported refers to. The MsgStatus subparameter 7640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // is primarily useful to indicate error conditions -- a 7650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // message without this subparameter is assumed to 7660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // indicate successful delivery (status == 0). 7670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (! mBearerData.messageStatusSet) { 768ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" + 76922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville (mUserData == null ? "also missing" : "does have") + 7700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville " userData)."); 7710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status = 0; 7720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 7730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status = mBearerData.errorClass << 8; 7740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status |= mBearerData.messageStatus; 7750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { 7770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); 7780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 78022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (mMessageBody != null) { 78122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (VDBG) Rlog.v(LOG_TAG, "SMS message body: '" + mMessageBody + "'"); 7820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville parseMessageBody(); 78322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville } else if ((mUserData != null) && VDBG) { 78422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville Rlog.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(mUserData) + "'"); 7850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 7880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 7890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parses a broadcast SMS, possibly containing a CMAS alert. 7900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 7910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbMessage parseBroadcastSms() { 7920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory); 7930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (bData == null) { 794ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.w(LOG_TAG, "BearerData.decode() returned null"); 7950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 7960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 7970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 798ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 799ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData)); 8000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); 8030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbLocation location = new SmsCbLocation(plmn); 8040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2, 8060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location, 8070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr, 8080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bData.priority, null, bData.cmasWarningInfo); 8090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@inheritDoc} 8130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 8150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public SmsConstants.MessageClass getMessageClass() { 8160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) { 8170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsConstants.MessageClass.CLASS_0; 8180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 8190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsConstants.MessageClass.UNKNOWN; 8200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Calculate the next message id, starting at 1 and iteratively 8250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * incrementing within the range 1..65535 remembering the state 8260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * via a persistent system property. (See C.S0015-B, v2.0, 8270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 4.3.1.5) Since this routine is expected to be accessed via via 8280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * binder-call, and hence should be thread-safe, it has been 8290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * synchronized. 8300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 831b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby synchronized static int getNextMessageId() { 8320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Testing and dialog with partners has indicated that 8330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // msgId==0 is (sometimes?) treated specially by lower levels. 8340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Specifically, the ID is not preserved for delivery ACKs. 8350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Hence, avoid 0 -- constraining the range to 1..65535. 8360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1); 8370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1); 8380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId); 839ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 840ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId); 841ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "readback gets " + 8420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID)); 8430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return msgId; 8450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Creates BearerData and Envelope from parameters for a Submit SMS. 8490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte stream for SubmitPdu. 8500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested, 8520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData userData) { 8530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): give this function a more meaningful name. 8560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): Make returning null from the getSubmitPdu 8600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * variations meaningful -- clean up the error feedback 8610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * mechanism, and avoid null pointer exceptions. 8620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 8650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * North America Plus Code : 8660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Convert + code to 011 and dial out for international SMS 8670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 8680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress destAddr = CdmaSmsAddress.parse( 8698409d93cf9f3ed23db12f24b4f49063ea416b30bJake Hamby PhoneNumberUtils.cdmaCheckAndProcessPlusCodeForSms(destAddrStr)); 8700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (destAddr == null) return null; 8710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville BearerData bearerData = new BearerData(); 8730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; 8740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.messageId = getNextMessageId(); 8760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.deliveryAckReq = statusReportRequested; 8780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.userAckReq = false; 8790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.readAckReq = false; 8800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.reportReq = false; 8810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bearerData.userData = userData; 8830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] encodedBearerData = BearerData.encode(bearerData); 885ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 886ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData); 887ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'"); 8880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 8890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (encodedBearerData == null) return null; 8900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int teleservice = bearerData.hasUserDataHeader ? 8920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; 8930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 8940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope envelope = new SmsEnvelope(); 8950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 8960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.teleService = teleservice; 8970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.destAddress = destAddr; 8980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.bearerReply = RETURN_ACK; 8990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville envelope.bearerData = encodedBearerData; 9000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): envelope looks to be a pointless class, get 9030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * rid of it. Also -- most of the envelope fields set here 9040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * are ignored, why? 9050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 9080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup): reference a spec and get rid of the ugly comments 9100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 9120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataOutputStream dos = new DataOutputStream(baos); 9130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(envelope.teleService); 9140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(0); //servicePresent 9150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(0); //serviceCategory 9160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.digitMode); 9170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberMode); 9180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.ton); // number_type 9190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberPlan); 9200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.numberOfDigits); 9210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits 9220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Subaddress is not supported. 9230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddressType 9240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddr_odd 9250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(0); //subaddr_nbr_of_digits 9260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(encodedBearerData.length); 9270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(encodedBearerData, 0, encodedBearerData.length); 9280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.close(); 9290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SubmitPdu pdu = new SubmitPdu(); 9310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu.encodedMessage = baos.toByteArray(); 9320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville pdu.encodedScAddress = null; 9330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return pdu; 9340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch(IOException ex) { 935ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "creating SubmitPdu failed: " + ex); 9360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return null; 9380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Creates byte array (pseudo pdu) from SMS object. 9420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Note: Do not call this method more than once per object! 9430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void createPdu() { 9450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsEnvelope env = mEnvelope; 9460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSmsAddress addr = env.origAddress; 9470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 9480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos)); 9490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 9510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.messageType); 9520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.teleService); 9530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.serviceCategory); 9540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.digitMode); 9560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberMode); 9570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.ton); 9580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberPlan); 9590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(addr.numberOfDigits); 9600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(addr.origBytes, 0, addr.origBytes.length); // digits 9610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.bearerReply); 9630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // CauseCode values: 9640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.replySeqNo); 9650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.errorClass); 9660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeByte(env.causeCode); 9670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //encoded BearerData: 9680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.writeInt(env.bearerData.length); 9690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.write(env.bearerData, 0, env.bearerData.length); 9700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dos.close(); 9710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * TODO(cleanup) -- The mPdu field is managed in 9740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a fragile manner, and it would be much nicer if 9750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * accessing the serialized representation used a less 9760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * fragile mechanism. Maybe the getPdu method could 9770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * generate a representation if there was not yet one? 9780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPdu = baos.toByteArray(); 9810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (IOException ex) { 982ded9c0af7fa49504c047275ed34c2d3b22bf0c3aWink Saville Rlog.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex); 9830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 9850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 9870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character 9880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 9890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private byte convertDtmfToAscii(byte dtmfDigit) { 9900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte asciiDigit; 9910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 9920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (dtmfDigit) { 9930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 0: asciiDigit = 68; break; // 'D' 9940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 1: asciiDigit = 49; break; // '1' 9950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 2: asciiDigit = 50; break; // '2' 9960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 3: asciiDigit = 51; break; // '3' 9970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 4: asciiDigit = 52; break; // '4' 9980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 5: asciiDigit = 53; break; // '5' 9990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 6: asciiDigit = 54; break; // '6' 10000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 7: asciiDigit = 55; break; // '7' 10010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 8: asciiDigit = 56; break; // '8' 10020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 9: asciiDigit = 57; break; // '9' 10030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 10: asciiDigit = 48; break; // '0' 10040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 11: asciiDigit = 42; break; // '*' 10050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 12: asciiDigit = 35; break; // '#' 10060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 13: asciiDigit = 65; break; // 'A' 10070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 14: asciiDigit = 66; break; // 'B' 10080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case 15: asciiDigit = 67; break; // 'C' 10090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 10100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville asciiDigit = 32; // Invalid DTMF code 10110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 10120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return asciiDigit; 10150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** This function shall be called to get the number of voicemails. 10180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 10190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 10200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /*package*/ int getNumOfVoicemails() { 10210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mBearerData.numberOfMessages; 10220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 10250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns a byte array that can be use to uniquely identify a received SMS message. 10260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * C.S0015-B 4.3.1.6 Unique Message Identification. 10270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 10280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return byte array uniquely identifying the message. 10290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @hide 10300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 10310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* package */ byte[] getIncomingSmsFingerprint() { 10320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ByteArrayOutputStream output = new ByteArrayOutputStream(); 10330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10349ebea45a36838f0547a9c30f7cd9c60b03aab3b4Siddartha Pothapragada output.write(mEnvelope.serviceCategory); 10350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.teleService); 10360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length); 10370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length); 10380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville output.write(mEnvelope.origSubaddress.origBytes, 0, 10390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mEnvelope.origSubaddress.origBytes.length); 10400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return output.toByteArray(); 10420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 10440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 10450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Returns the list of service category program data, if present. 10460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return a list of CdmaSmsCbProgramData objects, or null if not present 1047a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * @hide 10480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1049a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public ArrayList<CdmaSmsCbProgramData> getSmsCbProgramData() { 10500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mBearerData.serviceCategoryProgramData; 10510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 10520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 1053