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