1767a662ecde33c3979bf02b793d392aca0403162Wink Saville/* 2767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Copyright (C) 2008 The Android Open Source Project 3767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 4767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5767a662ecde33c3979bf02b793d392aca0403162Wink Saville * you may not use this file except in compliance with the License. 6767a662ecde33c3979bf02b793d392aca0403162Wink Saville * You may obtain a copy of the License at 7767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 8767a662ecde33c3979bf02b793d392aca0403162Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 9767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 10767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Unless required by applicable law or agreed to in writing, software 11767a662ecde33c3979bf02b793d392aca0403162Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13767a662ecde33c3979bf02b793d392aca0403162Wink Saville * See the License for the specific language governing permissions and 14767a662ecde33c3979bf02b793d392aca0403162Wink Saville * limitations under the License. 15767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 16767a662ecde33c3979bf02b793d392aca0403162Wink Saville 17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma; 18767a662ecde33c3979bf02b793d392aca0403162Wink Saville 19767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Parcel; 201f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalinkimport android.os.SystemProperties; 214e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shinimport android.telephony.PhoneNumberUtils; 223e3c3f80a90b156ff500076f8655647dfb317acfJake Hambyimport android.telephony.SmsCbLocation; 233e3c3f80a90b156ff500076f8655647dfb317acfJake Hambyimport android.telephony.SmsCbMessage; 243e3c3f80a90b156ff500076f8655647dfb317acfJake Hambyimport android.telephony.cdma.CdmaSmsCbProgramData; 25767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.util.Log; 263e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 27767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.IccUtils; 28767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsHeader; 29767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 301f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalinkimport com.android.internal.telephony.TelephonyProperties; 31767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.BearerData; 32767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress; 337d16427653e047e4901988e7ee04d637e65253b7Naveen Kallaimport com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress; 34767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 35767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.UserData; 36ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumarimport com.android.internal.util.BitwiseInputStream; 3749bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalinkimport com.android.internal.util.HexDump; 38767a662ecde33c3979bf02b793d392aca0403162Wink Saville 39767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.BufferedOutputStream; 40767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.ByteArrayInputStream; 41767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.ByteArrayOutputStream; 42767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.DataInputStream; 43767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.DataOutputStream; 44767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.IOException; 457b661fb3fc17f981bb122520791344891a3c1661Jake Hambyimport java.util.ArrayList; 463e3c3f80a90b156ff500076f8655647dfb317acfJake Hambyimport java.util.List; 473e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 483e3c3f80a90b156ff500076f8655647dfb317acfJake Hambyimport static android.telephony.SmsMessage.MessageClass; 49767a662ecde33c3979bf02b793d392aca0403162Wink Saville 508478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink/** 518478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * TODO(cleanup): these constants are disturbing... are they not just 528478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * different interpretations on one number? And if we did not have 538478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * terrible class name overlap, they would not need to be directly 548478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * imported like this. The class in this file could just as well be 558478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * named CdmaSmsMessage, could it not? 568478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 578478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 58767a662ecde33c3979bf02b793d392aca0403162Wink Saville/** 598478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * TODO(cleanup): internally returning null in many places makes 608478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * debugging very hard (among many other reasons) and should be made 61cbcd9be4104b3872902898b84fae92d1623fd8f1Jake Hamby * more meaningful (replaced with exceptions for example). Null 628478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * returns should only occur at the very outside of the module/class 638478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * scope. 648478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 658478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 668478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink/** 67767a662ecde33c3979bf02b793d392aca0403162Wink Saville * A Short Message Service message. 68767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 69767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 70767a662ecde33c3979bf02b793d392aca0403162Wink Savillepublic class SmsMessage extends SmsMessageBase { 71767a662ecde33c3979bf02b793d392aca0403162Wink Saville static final String LOG_TAG = "CDMA"; 7250f7ea53c3f356453fc4304b911c9a022290d924jsh static private final String LOGGABLE_TAG = "CDMA:SMS"; 73767a662ecde33c3979bf02b793d392aca0403162Wink Saville 74ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte TELESERVICE_IDENTIFIER = 0x00; 75ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte SERVICE_CATEGORY = 0x01; 76ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte ORIGINATING_ADDRESS = 0x02; 77ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte ORIGINATING_SUB_ADDRESS = 0x03; 78ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte DESTINATION_ADDRESS = 0x04; 79ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte DESTINATION_SUB_ADDRESS = 0x05; 80ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte BEARER_REPLY_OPTION = 0x06; 81ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte CAUSE_CODES = 0x07; 82ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private final static byte BEARER_DATA = 0x08; 83ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 84767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 85767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Status of a previously submitted SMS. 86767a662ecde33c3979bf02b793d392aca0403162Wink Saville * This field applies to SMS Delivery Acknowledge messages. 0 indicates success; 87767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Here, the error class is defined by the bits from 9-8, the status code by the bits from 7-0. 88767a662ecde33c3979bf02b793d392aca0403162Wink Saville * See C.S0015-B, v2.0, 4.5.21 for a detailed description of possible values. 89767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 90767a662ecde33c3979bf02b793d392aca0403162Wink Saville private int status; 91767a662ecde33c3979bf02b793d392aca0403162Wink Saville 92767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** Specifies if a return of an acknowledgment is requested for send SMS */ 93767a662ecde33c3979bf02b793d392aca0403162Wink Saville private static final int RETURN_NO_ACK = 0; 94767a662ecde33c3979bf02b793d392aca0403162Wink Saville private static final int RETURN_ACK = 1; 95767a662ecde33c3979bf02b793d392aca0403162Wink Saville 96767a662ecde33c3979bf02b793d392aca0403162Wink Saville private SmsEnvelope mEnvelope; 97767a662ecde33c3979bf02b793d392aca0403162Wink Saville private BearerData mBearerData; 98767a662ecde33c3979bf02b793d392aca0403162Wink Saville 99767a662ecde33c3979bf02b793d392aca0403162Wink Saville public static class SubmitPdu extends SubmitPduBase { 100767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 101767a662ecde33c3979bf02b793d392aca0403162Wink Saville 102767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 103767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Create an SmsMessage from a raw PDU. 104767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: In CDMA the PDU is just a byte representation of the received Sms. 105767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 106767a662ecde33c3979bf02b793d392aca0403162Wink Saville public static SmsMessage createFromPdu(byte[] pdu) { 107767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsMessage msg = new SmsMessage(); 108767a662ecde33c3979bf02b793d392aca0403162Wink Saville 109767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 110767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.parsePdu(pdu); 111767a662ecde33c3979bf02b793d392aca0403162Wink Saville return msg; 112767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (RuntimeException ex) { 113767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 114767a662ecde33c3979bf02b793d392aca0403162Wink Saville return null; 115767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 116767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 117767a662ecde33c3979bf02b793d392aca0403162Wink Saville 118767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 119767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp. 120767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: Only primitive fields are set. 121767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 122767a662ecde33c3979bf02b793d392aca0403162Wink Saville public static SmsMessage newFromParcel(Parcel p) { 123767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Note: Parcel.readByte actually reads one Int and masks to byte 124767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsMessage msg = new SmsMessage(); 125767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsEnvelope env = new SmsEnvelope(); 126767a662ecde33c3979bf02b793d392aca0403162Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 1277d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress(); 128767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[] data; 129767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte count; 130767a662ecde33c3979bf02b793d392aca0403162Wink Saville int countInt; 131e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville int addressDigitMode; 132767a662ecde33c3979bf02b793d392aca0403162Wink Saville 133767a662ecde33c3979bf02b793d392aca0403162Wink Saville //currently not supported by the modem-lib: env.mMessageType 134767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.teleService = p.readInt(); //p_cur->uTeleserviceID 135767a662ecde33c3979bf02b793d392aca0403162Wink Saville 136767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (0 != p.readByte()) { //p_cur->bIsServicePresent 137767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST; 138767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 139767a662ecde33c3979bf02b793d392aca0403162Wink Saville else { 140767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) { 141767a662ecde33c3979bf02b793d392aca0403162Wink Saville // assume type ACK 142767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE; 143767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 144767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 145767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 146767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 147767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.serviceCategory = p.readInt(); //p_cur->uServicecategory 148767a662ecde33c3979bf02b793d392aca0403162Wink Saville 149767a662ecde33c3979bf02b793d392aca0403162Wink Saville // address 150e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville addressDigitMode = p.readInt(); 151e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville addr.digitMode = (byte) (0xFF & addressDigitMode); //p_cur->sAddress.digit_mode 152767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberMode = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_mode 153767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.ton = p.readInt(); //p_cur->sAddress.number_type 154767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberPlan = (byte) (0xFF & p.readInt()); //p_cur->sAddress.number_plan 155767a662ecde33c3979bf02b793d392aca0403162Wink Saville count = p.readByte(); //p_cur->sAddress.number_of_digits 156767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberOfDigits = count; 157767a662ecde33c3979bf02b793d392aca0403162Wink Saville data = new byte[count]; 158767a662ecde33c3979bf02b793d392aca0403162Wink Saville //p_cur->sAddress.digits[digitCount] 159767a662ecde33c3979bf02b793d392aca0403162Wink Saville for (int index=0; index < count; index++) { 160767a662ecde33c3979bf02b793d392aca0403162Wink Saville data[index] = p.readByte(); 161e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 162e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville // convert the value if it is 4-bit DTMF to 8 bit 163e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 164e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville data[index] = msg.convertDtmfToAscii(data[index]); 165e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville } 166767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 167e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 168767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.origBytes = data; 169767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1707d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType 1717d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd 1727d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla count = p.readByte(); // p_cur->sSubAddress.number_of_digits 1737d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla 1747d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla if (count < 0) { 1757d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla count = 0; 176767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 177767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1787d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla // p_cur->sSubAddress.digits[digitCount] : 1797d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla 1807d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla data = new byte[count]; 1817d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla 1827d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla for (int index = 0; index < count; ++index) { 1837d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla data[index] = p.readByte(); 1847d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla } 1857d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla 1867d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla subaddr.origBytes = data; 1877d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla 188767a662ecde33c3979bf02b793d392aca0403162Wink Saville /* currently not supported by the modem-lib: 189767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.bearerReply 190767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.replySeqNo 191767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.errorClass 192767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.causeCode 193767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 194767a662ecde33c3979bf02b793d392aca0403162Wink Saville 195767a662ecde33c3979bf02b793d392aca0403162Wink Saville // bearer data 196767a662ecde33c3979bf02b793d392aca0403162Wink Saville countInt = p.readInt(); //p_cur->uBearerDataLen 1973e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby if (countInt < 0) { 1983e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby countInt = 0; 1990c49f03a0429b5c0c4a619256f7bca86a4997ae8Jake Hamby } 2000c49f03a0429b5c0c4a619256f7bca86a4997ae8Jake Hamby 2013e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby data = new byte[countInt]; 2023e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby for (int index=0; index < countInt; index++) { 2033e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby data[index] = p.readByte(); 2043e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby } 2053e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby // BD gets further decoded when accessed in SMSDispatcher 2063e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby env.bearerData = data; 2073e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 208767a662ecde33c3979bf02b793d392aca0403162Wink Saville // link the the filled objects to the SMS 209767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.origAddress = addr; 2107d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla env.origSubaddress = subaddr; 211767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.originatingAddress = addr; 212767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.mEnvelope = env; 213767a662ecde33c3979bf02b793d392aca0403162Wink Saville 214767a662ecde33c3979bf02b793d392aca0403162Wink Saville // create byte stream representation for transportation through the layers. 215767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.createPdu(); 216767a662ecde33c3979bf02b793d392aca0403162Wink Saville 217767a662ecde33c3979bf02b793d392aca0403162Wink Saville return msg; 218767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 219767a662ecde33c3979bf02b793d392aca0403162Wink Saville 220767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 221767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Create an SmsMessage from an SMS EF record. 222767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 223767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param index Index of SMS record. This should be index in ArrayList 224767a662ecde33c3979bf02b793d392aca0403162Wink Saville * returned by RuimSmsInterfaceManager.getAllMessagesFromIcc + 1. 225767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param data Record data. 226767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @return An SmsMessage representing the record. 227767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 228767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @hide 229767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 230767a662ecde33c3979bf02b793d392aca0403162Wink Saville public static SmsMessage createFromEfRecord(int index, byte[] data) { 231767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 232767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsMessage msg = new SmsMessage(); 233767a662ecde33c3979bf02b793d392aca0403162Wink Saville 234767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.indexOnIcc = index; 235767a662ecde33c3979bf02b793d392aca0403162Wink Saville 236767a662ecde33c3979bf02b793d392aca0403162Wink Saville // First byte is status: RECEIVED_READ, RECEIVED_UNREAD, STORED_SENT, 237767a662ecde33c3979bf02b793d392aca0403162Wink Saville // or STORED_UNSENT 238767a662ecde33c3979bf02b793d392aca0403162Wink Saville // See 3GPP2 C.S0023 3.4.27 239767a662ecde33c3979bf02b793d392aca0403162Wink Saville if ((data[0] & 1) == 0) { 240767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "SMS parsing failed: Trying to parse a free record"); 241767a662ecde33c3979bf02b793d392aca0403162Wink Saville return null; 242767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 243767a662ecde33c3979bf02b793d392aca0403162Wink Saville msg.statusOnIcc = data[0] & 0x07; 244767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 245767a662ecde33c3979bf02b793d392aca0403162Wink Saville 246767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Second byte is the MSG_LEN, length of the message 247767a662ecde33c3979bf02b793d392aca0403162Wink Saville // See 3GPP2 C.S0023 3.4.27 248767a662ecde33c3979bf02b793d392aca0403162Wink Saville int size = data[1]; 249767a662ecde33c3979bf02b793d392aca0403162Wink Saville 250767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Note: Data may include trailing FF's. That's OK; message 251767a662ecde33c3979bf02b793d392aca0403162Wink Saville // should still parse correctly. 252767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[] pdu = new byte[size]; 253767a662ecde33c3979bf02b793d392aca0403162Wink Saville System.arraycopy(data, 2, pdu, 0, size); 254767a662ecde33c3979bf02b793d392aca0403162Wink Saville // the message has to be parsed before it can be displayed 255767a662ecde33c3979bf02b793d392aca0403162Wink Saville // see gsm.SmsMessage 256ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar msg.parsePduFromEfRecord(pdu); 257767a662ecde33c3979bf02b793d392aca0403162Wink Saville return msg; 258767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (RuntimeException ex) { 259767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex); 260767a662ecde33c3979bf02b793d392aca0403162Wink Saville return null; 261767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 262767a662ecde33c3979bf02b793d392aca0403162Wink Saville 263767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 264767a662ecde33c3979bf02b793d392aca0403162Wink Saville 265767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 266767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 267767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 268767a662ecde33c3979bf02b793d392aca0403162Wink Saville public static int getTPLayerLengthForPDU(String pdu) { 269767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "getTPLayerLengthForPDU: is not supported in CDMA mode."); 270767a662ecde33c3979bf02b793d392aca0403162Wink Saville return 0; 271767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 272767a662ecde33c3979bf02b793d392aca0403162Wink Saville 273767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 27464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): why do getSubmitPdu methods take an scAddr input 27564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * and do nothing with it? GSM allows us to specify a SC (eg, 27664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * when responding to an SMS that explicitly requests the response 27764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * is sent to a specific SC), or pass null to use the default 27864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * value. Is there no similar notion in CDMA? Or do we just not 27964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * have it hooked up? 28064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 28164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 28264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 283767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Get an SMS-SUBMIT PDU for a destination address and a message 284767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 2858478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * @param scAddr Service Centre address. Null means use default. 2868478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * @param destAddr Address of the recipient. 287767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param message String representation of the message payload. 288767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param statusReportRequested Indicates whether a report is requested for this message. 2899e397775e18f369f7855affd23a3ce6a24053218Jake Hamby * @param smsHeader Array containing the data for the User Data Header, preceded 290767a662ecde33c3979bf02b793d392aca0403162Wink Saville * by the Element Identifiers. 291767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 292767a662ecde33c3979bf02b793d392aca0403162Wink Saville * address, if applicable, and the encoded message. 293767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Returns null on encode error. 294767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @hide 295767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 29664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message, 29764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink boolean statusReportRequested, SmsHeader smsHeader) { 29864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 2998478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink /** 30064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): Do we really want silent failure like this? 30164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * Would it not be much more reasonable to make sure we don't 30264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * call this function if we really want nothing done? 3038478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 3048478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink if (message == null || destAddr == null) { 305767a662ecde33c3979bf02b793d392aca0403162Wink Saville return null; 306767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 307767a662ecde33c3979bf02b793d392aca0403162Wink Saville 3088478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink UserData uData = new UserData(); 3098478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink uData.payloadStr = message; 31064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink uData.userDataHeader = smsHeader; 31164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 312767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 313767a662ecde33c3979bf02b793d392aca0403162Wink Saville 314767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 315390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * Get an SMS-SUBMIT PDU for a data message to a destination address and port. 316767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 31764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * @param scAddr Service Centre address. null == use default 31864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * @param destAddr the address of the destination for the message 31964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * @param destPort the port to deliver the message to at the 320767a662ecde33c3979bf02b793d392aca0403162Wink Saville * destination 321767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param data the data for the message 322767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @return a <code>SubmitPdu</code> containing the encoded SC 323767a662ecde33c3979bf02b793d392aca0403162Wink Saville * address, if applicable, and the encoded message. 324767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Returns null on encode error. 325767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 3261f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort, 32764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink byte[] data, boolean statusReportRequested) { 328767a662ecde33c3979bf02b793d392aca0403162Wink Saville 3298478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink /** 33064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): this is not a general-purpose SMS creation 33164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * method, but rather something specialized to messages 33264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * containing OCTET encoded (meaning non-human-readable) user 33364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * data. The name should reflect that, and not just overload. 3348478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 335767a662ecde33c3979bf02b793d392aca0403162Wink Saville 33664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); 33764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink portAddrs.destPort = destPort; 33864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink portAddrs.origPort = 0; 33964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink portAddrs.areEightBits = false; 34064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 3418478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink SmsHeader smsHeader = new SmsHeader(); 34264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink smsHeader.portAddrs = portAddrs; 343767a662ecde33c3979bf02b793d392aca0403162Wink Saville 3448478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink UserData uData = new UserData(); 3458478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink uData.userDataHeader = smsHeader; 34683917db040bd7498ebca3b74f879dc1c9e223d8eTammo Spalink uData.msgEncoding = UserData.ENCODING_OCTET; 3478478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink uData.msgEncodingSet = true; 34883917db040bd7498ebca3b74f879dc1c9e223d8eTammo Spalink uData.payload = data; 349767a662ecde33c3979bf02b793d392aca0403162Wink Saville 35064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return privateGetSubmitPdu(destAddr, statusReportRequested, uData); 351767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 352767a662ecde33c3979bf02b793d392aca0403162Wink Saville 353767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 354fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * Get an SMS-SUBMIT PDU for a data message to a destination address & port 355a94945d3a1cf23caf33759eb1de84195d3fcb37bTammo Spalink * 356fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @param destAddr the address of the destination for the message 3579e397775e18f369f7855affd23a3ce6a24053218Jake Hamby * @param userData the data for the message 358fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @param statusReportRequested Indicates whether a report is requested for this message. 359fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @return a <code>SubmitPdu</code> containing the encoded SC 360fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * address, if applicable, and the encoded message. 361fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * Returns null on encode error. 362a94945d3a1cf23caf33759eb1de84195d3fcb37bTammo Spalink */ 363fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink public static SubmitPdu getSubmitPdu(String destAddr, UserData userData, 364fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink boolean statusReportRequested) { 365fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink return privateGetSubmitPdu(destAddr, statusReportRequested, userData); 366a94945d3a1cf23caf33759eb1de84195d3fcb37bTammo Spalink } 367a94945d3a1cf23caf33759eb1de84195d3fcb37bTammo Spalink 368a94945d3a1cf23caf33759eb1de84195d3fcb37bTammo Spalink /** 369767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 370767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 371767a662ecde33c3979bf02b793d392aca0403162Wink Saville public int getProtocolIdentifier() { 372767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "getProtocolIdentifier: is not supported in CDMA mode."); 373767a662ecde33c3979bf02b793d392aca0403162Wink Saville // (3GPP TS 23.040): "no interworking, but SME to SME protocol": 374767a662ecde33c3979bf02b793d392aca0403162Wink Saville return 0; 375767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 376767a662ecde33c3979bf02b793d392aca0403162Wink Saville 377767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 378767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 379767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 380767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isReplace() { 381767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "isReplace: is not supported in CDMA mode."); 382767a662ecde33c3979bf02b793d392aca0403162Wink Saville return false; 383767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 384767a662ecde33c3979bf02b793d392aca0403162Wink Saville 385767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 386767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@inheritDoc} 387767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 388767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 389767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isCphsMwiMessage() { 390767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "isCphsMwiMessage: is not supported in CDMA mode."); 391767a662ecde33c3979bf02b793d392aca0403162Wink Saville return false; 392767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 393767a662ecde33c3979bf02b793d392aca0403162Wink Saville 394767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 395767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@inheritDoc} 396767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 397767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isMWIClearMessage() { 39864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return ((mBearerData != null) && (mBearerData.numberOfMessages == 0)); 399767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 400767a662ecde33c3979bf02b793d392aca0403162Wink Saville 401767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 402767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@inheritDoc} 403767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 404767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isMWISetMessage() { 40564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return ((mBearerData != null) && (mBearerData.numberOfMessages > 0)); 406767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 407767a662ecde33c3979bf02b793d392aca0403162Wink Saville 408767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 409767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@inheritDoc} 410767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 411767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isMwiDontStore() { 41264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return ((mBearerData != null) && 41364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink (mBearerData.numberOfMessages > 0) && 41464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink (mBearerData.userData == null)); 415767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 416767a662ecde33c3979bf02b793d392aca0403162Wink Saville 417767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 418767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Returns the status for a previously submitted message. 419767a662ecde33c3979bf02b793d392aca0403162Wink Saville * For not interfering with status codes from GSM, this status code is 420767a662ecde33c3979bf02b793d392aca0403162Wink Saville * shifted to the bits 31-16. 421767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 422767a662ecde33c3979bf02b793d392aca0403162Wink Saville public int getStatus() { 42364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink return (status << 16); 424767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 425767a662ecde33c3979bf02b793d392aca0403162Wink Saville 426d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink /** Return true iff the bearer data message type is DELIVERY_ACK. */ 427767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isStatusReportMessage() { 428d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK); 429767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 430767a662ecde33c3979bf02b793d392aca0403162Wink Saville 431767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 432767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: This function is a GSM specific functionality which is not supported in CDMA mode. 433767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 434767a662ecde33c3979bf02b793d392aca0403162Wink Saville public boolean isReplyPathPresent() { 435767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(LOG_TAG, "isReplyPathPresent: is not supported in CDMA mode."); 436767a662ecde33c3979bf02b793d392aca0403162Wink Saville return false; 437767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 438767a662ecde33c3979bf02b793d392aca0403162Wink Saville 439767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 440fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * Calculate the number of septets needed to encode the message. 441fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * 442fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @param messageBody the message to encode 443fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @param use7bitOnly ignore (but still count) illegal characters if true 444fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink * @return TextEncodingDetails 445fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink */ 446fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink public static TextEncodingDetails calculateLength(CharSequence messageBody, 447fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink boolean use7bitOnly) { 44817f616823a562ceb3a008f91e05d43bc56d37caeJake Hamby return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly); 449fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink } 450fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink 451fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink /** 452767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Returns the teleservice type of the message. 453767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @return the teleservice: 454767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_NOT_SET}, 455767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WMT}, 456767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WEMT}, 457767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_VMN}, 458767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#TELESERVICE_WAP} 459767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 46083fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph /* package */ int getTeleService() { 461767a662ecde33c3979bf02b793d392aca0403162Wink Saville return mEnvelope.teleService; 462767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 463767a662ecde33c3979bf02b793d392aca0403162Wink Saville 464767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 46583fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph * Returns the message type of the message. 46683fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph * @return the message type: 46783fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_POINT_TO_POINT}, 46883fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_BROADCAST}, 46983fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph * {@link com.android.internal.telephony.cdma.sms.SmsEnvelope#MESSAGE_TYPE_ACKNOWLEDGE}, 47083fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph */ 47183fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph /* package */ int getMessageType() { 47215c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby // NOTE: mEnvelope.messageType is not set correctly for cell broadcasts with some RILs. 47315c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby // Use the service category parameter to detect CMAS and other cell broadcast messages. 47415c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby if (mEnvelope.serviceCategory != 0) { 47515c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby return SmsEnvelope.MESSAGE_TYPE_BROADCAST; 47615c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby } else { 47715c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby return SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 47815c257eb8f077fc4f6c95f8a7bc84dd9a7b39c61Jake Hamby } 47983fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph } 48083fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph 48183fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph /** 482767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Decodes pdu to an empty SMS object. 483767a662ecde33c3979bf02b793d392aca0403162Wink Saville * In the CDMA case the pdu is just an internal byte stream representation 484767a662ecde33c3979bf02b793d392aca0403162Wink Saville * of the SMS Java-object. 485767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @see #createPdu() 486767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 487767a662ecde33c3979bf02b793d392aca0403162Wink Saville private void parsePdu(byte[] pdu) { 488767a662ecde33c3979bf02b793d392aca0403162Wink Saville ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 48964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink DataInputStream dis = new DataInputStream(bais); 490767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte length; 491e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville int bearerDataLength; 492767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsEnvelope env = new SmsEnvelope(); 493767a662ecde33c3979bf02b793d392aca0403162Wink Saville CdmaSmsAddress addr = new CdmaSmsAddress(); 494767a662ecde33c3979bf02b793d392aca0403162Wink Saville 495767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 496767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.messageType = dis.readInt(); 497767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.teleService = dis.readInt(); 498767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.serviceCategory = dis.readInt(); 499767a662ecde33c3979bf02b793d392aca0403162Wink Saville 500767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.digitMode = dis.readByte(); 501767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberMode = dis.readByte(); 502767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.ton = dis.readByte(); 503767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberPlan = dis.readByte(); 504767a662ecde33c3979bf02b793d392aca0403162Wink Saville 505767a662ecde33c3979bf02b793d392aca0403162Wink Saville length = dis.readByte(); 506767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.numberOfDigits = length; 507767a662ecde33c3979bf02b793d392aca0403162Wink Saville addr.origBytes = new byte[length]; 508767a662ecde33c3979bf02b793d392aca0403162Wink Saville dis.read(addr.origBytes, 0, length); // digits 509767a662ecde33c3979bf02b793d392aca0403162Wink Saville 510767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.bearerReply = dis.readInt(); 511767a662ecde33c3979bf02b793d392aca0403162Wink Saville // CauseCode values: 512767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.replySeqNo = dis.readByte(); 513767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.errorClass = dis.readByte(); 514767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.causeCode = dis.readByte(); 515767a662ecde33c3979bf02b793d392aca0403162Wink Saville 516767a662ecde33c3979bf02b793d392aca0403162Wink Saville //encoded BearerData: 517e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville bearerDataLength = dis.readInt(); 518e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville env.bearerData = new byte[bearerDataLength]; 519e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville dis.read(env.bearerData, 0, bearerDataLength); 520767a662ecde33c3979bf02b793d392aca0403162Wink Saville dis.close(); 521767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (Exception ex) { 522767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(LOG_TAG, "createFromPdu: conversion from byte array to object failed: " + ex); 523767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 524767a662ecde33c3979bf02b793d392aca0403162Wink Saville 525767a662ecde33c3979bf02b793d392aca0403162Wink Saville // link the filled objects to this SMS 526767a662ecde33c3979bf02b793d392aca0403162Wink Saville originatingAddress = addr; 527767a662ecde33c3979bf02b793d392aca0403162Wink Saville env.origAddress = addr; 528767a662ecde33c3979bf02b793d392aca0403162Wink Saville mEnvelope = env; 5295082fd58e33aa54d760459de3368912c37864a4fSatish Roddom mPdu = pdu; 530767a662ecde33c3979bf02b793d392aca0403162Wink Saville 531767a662ecde33c3979bf02b793d392aca0403162Wink Saville parseSms(); 532767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 533767a662ecde33c3979bf02b793d392aca0403162Wink Saville 534767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 535ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0 536ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar */ 537ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar private void parsePduFromEfRecord(byte[] pdu) { 538ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar ByteArrayInputStream bais = new ByteArrayInputStream(pdu); 539ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar DataInputStream dis = new DataInputStream(bais); 540ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar SmsEnvelope env = new SmsEnvelope(); 541ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar CdmaSmsAddress addr = new CdmaSmsAddress(); 542ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress(); 543ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 544ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar try { 545ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.messageType = dis.readByte(); 546ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 547ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar while (dis.available() > 0) { 548ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar int parameterId = dis.readByte(); 549ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar int parameterLen = dis.readByte(); 550ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar byte[] parameterData = new byte[parameterLen]; 551ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 552ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar switch (parameterId) { 553ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case TELESERVICE_IDENTIFIER: 554ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar /* 555ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * 16 bit parameter that identifies which upper layer 556ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * service access point is sending or should receive 557ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * this message 558ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar */ 559ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.teleService = dis.readUnsignedShort(); 560ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.i(LOG_TAG, "teleservice = " + env.teleService); 561ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 562ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case SERVICE_CATEGORY: 563ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar /* 564ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * 16 bit parameter that identifies type of service as 565ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar * in 3GPP2 C.S0015-0 Table 3.4.3.2-1 566ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar */ 567ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.serviceCategory = dis.readUnsignedShort(); 568ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 569ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case ORIGINATING_ADDRESS: 570ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case DESTINATION_ADDRESS: 571ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.read(parameterData, 0, parameterLen); 572ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar BitwiseInputStream addrBis = new BitwiseInputStream(parameterData); 573ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.digitMode = addrBis.read(1); 574ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.numberMode = addrBis.read(1); 575ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar int numberType = 0; 576ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 577ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar numberType = addrBis.read(3); 578ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.ton = numberType; 579ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 580ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) 581ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.numberPlan = addrBis.read(4); 582ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 583ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 584ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.numberOfDigits = addrBis.read(8); 585ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 586ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar byte[] data = new byte[addr.numberOfDigits]; 587ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar byte b = 0x00; 588ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 589ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) { 590ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */ 591ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar for (int index = 0; index < addr.numberOfDigits; index++) { 592ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar b = (byte) (0xF & addrBis.read(4)); 593ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar // convert the value if it is 4-bit DTMF to 8 594ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar // bit 595ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar data[index] = convertDtmfToAscii(b); 596ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 597ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) { 598ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) { 599ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar for (int index = 0; index < addr.numberOfDigits; index++) { 600ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar b = (byte) (0xFF & addrBis.read(8)); 601ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar data[index] = b; 602ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 603ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 604ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) { 605ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (numberType == 2) 606ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.e(LOG_TAG, "TODO: Originating Addr is email id"); 607ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar else 608ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.e(LOG_TAG, 609ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar "TODO: Originating Addr is data network address"); 610ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } else { 611ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.e(LOG_TAG, "Originating Addr is of incorrect type"); 612ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 613ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } else { 614ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.e(LOG_TAG, "Incorrect Digit mode"); 615ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 616ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar addr.origBytes = data; 617ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.i(LOG_TAG, "Originating Addr=" + addr.toString()); 618ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 619ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case ORIGINATING_SUB_ADDRESS: 620ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case DESTINATION_SUB_ADDRESS: 621ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.read(parameterData, 0, parameterLen); 622ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData); 623ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar subAddr.type = subAddrBis.read(3); 624ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar subAddr.odd = subAddrBis.readByteArray(1)[0]; 625ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar int subAddrLen = subAddrBis.read(8); 626ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar byte[] subdata = new byte[subAddrLen]; 627ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar for (int index = 0; index < subAddrLen; index++) { 628ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar b = (byte) (0xFF & subAddrBis.read(4)); 629ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar // convert the value if it is 4-bit DTMF to 8 bit 630ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar subdata[index] = convertDtmfToAscii(b); 631ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 632ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar subAddr.origBytes = subdata; 633ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 634ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case BEARER_REPLY_OPTION: 635ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.read(parameterData, 0, parameterLen); 636ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData); 637ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.bearerReply = replyOptBis.read(6); 638ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 639ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case CAUSE_CODES: 640ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.read(parameterData, 0, parameterLen); 641ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar BitwiseInputStream ccBis = new BitwiseInputStream(parameterData); 642ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.replySeqNo = ccBis.readByteArray(6)[0]; 643ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.errorClass = ccBis.readByteArray(2)[0]; 644ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar if (env.errorClass != 0x00) 645ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.causeCode = ccBis.readByteArray(8)[0]; 646ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 647ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar case BEARER_DATA: 648ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.read(parameterData, 0, parameterLen); 649ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.bearerData = parameterData; 650ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar break; 651ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar default: 652ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar throw new Exception("unsupported parameterId (" + parameterId + ")"); 653ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 654ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 655ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar bais.close(); 656ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar dis.close(); 657ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } catch (Exception ex) { 658ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex); 659ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 660ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 661ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar // link the filled objects to this SMS 662ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar originatingAddress = addr; 663ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.origAddress = addr; 664ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar env.origSubaddress = subAddr; 665ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar mEnvelope = env; 666ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar mPdu = pdu; 667ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 668ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar parseSms(); 669ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar } 670ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar 671ee7d1973ff3cd7c9c8744696901b37833027cafbRekha Kumar /** 672767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Parses a SMS message from its BearerData stream. (mobile-terminated only) 673767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 674767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void parseSms() { 675c84401fb8b3ed90039bd132b343852303ef88ce6yong liu // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6 676c84401fb8b3ed90039bd132b343852303ef88ce6yong liu // It contains only an 8-bit number with the number of messages waiting 677c84401fb8b3ed90039bd132b343852303ef88ce6yong liu if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) { 678c84401fb8b3ed90039bd132b343852303ef88ce6yong liu mBearerData = new BearerData(); 679c84401fb8b3ed90039bd132b343852303ef88ce6yong liu if (mEnvelope.bearerData != null) { 680c84401fb8b3ed90039bd132b343852303ef88ce6yong liu mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0]; 681c84401fb8b3ed90039bd132b343852303ef88ce6yong liu } 68243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) { 683c84401fb8b3ed90039bd132b343852303ef88ce6yong liu Log.d(LOG_TAG, "parseSms: get MWI " + 684c84401fb8b3ed90039bd132b343852303ef88ce6yong liu Integer.toString(mBearerData.numberOfMessages)); 685c84401fb8b3ed90039bd132b343852303ef88ce6yong liu } 686c84401fb8b3ed90039bd132b343852303ef88ce6yong liu return; 687c84401fb8b3ed90039bd132b343852303ef88ce6yong liu } 68883917db040bd7498ebca3b74f879dc1c9e223d8eTammo Spalink mBearerData = BearerData.decode(mEnvelope.bearerData); 68950f7ea53c3f356453fc4304b911c9a022290d924jsh if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 69049bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink Log.d(LOG_TAG, "MT raw BearerData = '" + 69149bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink HexDump.toHexString(mEnvelope.bearerData) + "'"); 69249bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData); 69349bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink } 69483917db040bd7498ebca3b74f879dc1c9e223d8eTammo Spalink messageRef = mBearerData.messageId; 69564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if (mBearerData.userData != null) { 69664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink userData = mBearerData.userData.payload; 69764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink userDataHeader = mBearerData.userData.userDataHeader; 69864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink messageBody = mBearerData.userData.payloadStr; 69964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink } 700767a662ecde33c3979bf02b793d392aca0403162Wink Saville 701767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (originatingAddress != null) { 702767a662ecde33c3979bf02b793d392aca0403162Wink Saville originatingAddress.address = new String(originatingAddress.origBytes); 70343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v(LOG_TAG, "SMS originating address: " 704767a662ecde33c3979bf02b793d392aca0403162Wink Saville + originatingAddress.address); 705767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 706767a662ecde33c3979bf02b793d392aca0403162Wink Saville 707baae313f896d8048f23e4acc76e554c8aa4667bdTammo Spalink if (mBearerData.msgCenterTimeStamp != null) { 708baae313f896d8048f23e4acc76e554c8aa4667bdTammo Spalink scTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true); 709767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 710767a662ecde33c3979bf02b793d392aca0403162Wink Saville 71143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis); 712767a662ecde33c3979bf02b793d392aca0403162Wink Saville 713d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1) 714d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) { 715d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // The BearerData MsgStatus subparameter should only be 716d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // included for DELIVERY_ACK messages. If it occurred for 717d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // other messages, it would be unclear what the status 718d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // being reported refers to. The MsgStatus subparameter 719d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // is primarily useful to indicate error conditions -- a 720d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // message without this subparameter is assumed to 721d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // indicate successful delivery (status == 0). 722d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink if (! mBearerData.messageStatusSet) { 723d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" + 724d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink (userData == null ? "also missing" : "does have") + 725d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink " userData)."); 726d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink status = 0; 727d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } else { 728d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink status = mBearerData.errorClass << 8; 729d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink status |= mBearerData.messageStatus; 730d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 731d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) { 732d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink throw new RuntimeException("Unsupported message type: " + mBearerData.messageType); 733767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 734767a662ecde33c3979bf02b793d392aca0403162Wink Saville 735767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (messageBody != null) { 73643a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) Log.v(LOG_TAG, "SMS message body: '" + messageBody + "'"); 737767a662ecde33c3979bf02b793d392aca0403162Wink Saville parseMessageBody(); 73843a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato } else if ((userData != null) && (false)) { 7398c49d32cb9980959c402eaa243fd5129cd9942fcTammo Spalink Log.v(LOG_TAG, "SMS payload: '" + IccUtils.bytesToHexString(userData) + "'"); 740767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 741767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 742767a662ecde33c3979bf02b793d392aca0403162Wink Saville 743767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 7443e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby * Parses a broadcast SMS, possibly containing a CMAS alert. 7453e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby */ 7463e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby SmsCbMessage parseBroadcastSms() { 7473e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory); 7483e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby if (bData == null) { 7493e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby Log.w(LOG_TAG, "BearerData.decode() returned null"); 7503e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby return null; 7513e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby } 7523e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 7533e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 7543e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby Log.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData)); 7553e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby } 7563e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 7573e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); 7583e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby SmsCbLocation location = new SmsCbLocation(plmn); 7593e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 7603e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2, 7613e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE, bData.messageId, location, 7623e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby mEnvelope.serviceCategory, bData.getLanguage(), bData.userData.payloadStr, 7633e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby bData.priority, null, bData.cmasWarningInfo); 7643e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby } 7653e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 7663e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby /** 767767a662ecde33c3979bf02b793d392aca0403162Wink Saville * {@inheritDoc} 768767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 769767a662ecde33c3979bf02b793d392aca0403162Wink Saville public MessageClass getMessageClass() { 7708c49d32cb9980959c402eaa243fd5129cd9942fcTammo Spalink if (BearerData.DISPLAY_MODE_IMMEDIATE == mBearerData.displayMode ) { 771767a662ecde33c3979bf02b793d392aca0403162Wink Saville return MessageClass.CLASS_0; 772767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 773767a662ecde33c3979bf02b793d392aca0403162Wink Saville return MessageClass.UNKNOWN; 774767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 775767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 776767a662ecde33c3979bf02b793d392aca0403162Wink Saville 777767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 77898a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink * Calculate the next message id, starting at 1 and iteratively 77998a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink * incrementing within the range 1..65535 remembering the state 7801f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink * via a persistent system property. (See C.S0015-B, v2.0, 78198a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink * 4.3.1.5) Since this routine is expected to be accessed via via 782cbcd9be4104b3872902898b84fae92d1623fd8f1Jake Hamby * binder-call, and hence should be thread-safe, it has been 78398a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink * synchronized. 784767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 7857b661fb3fc17f981bb122520791344891a3c1661Jake Hamby synchronized static int getNextMessageId() { 78698a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink // Testing and dialog with partners has indicated that 78798a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink // msgId==0 is (sometimes?) treated specially by lower levels. 78898a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink // Specifically, the ID is not preserved for delivery ACKs. 78998a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink // Hence, avoid 0 -- constraining the range to 1..65535. 79098a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 1); 79198a5ba78f99f6537b34b673521f7d4ab9893c80bTammo Spalink String nextMsgId = Integer.toString((msgId % 0xFFFF) + 1); 7921f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId); 79350f7ea53c3f356453fc4304b911c9a022290d924jsh if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 7941f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId); 7951f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink Log.d(LOG_TAG, "readback gets " + 7961f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID)); 797767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 7981f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink return msgId; 799767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 800767a662ecde33c3979bf02b793d392aca0403162Wink Saville 801767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 8028478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * Creates BearerData and Envelope from parameters for a Submit SMS. 8038478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * @return byte stream for SubmitPdu. 804767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 8058478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested, 80664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink UserData userData) { 8078478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8088478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink /** 8098478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * TODO(cleanup): give this function a more meaningful name. 8108478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 8118478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8121424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink /** 8131424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink * TODO(cleanup): Make returning null from the getSubmitPdu 8141424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink * variations meaningful -- clean up the error feedback 8151424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink * mechanism, and avoid null pointer exceptions. 8161424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink */ 8171424fe0059a3fe163fb98bad807a1eb635b0a161Tammo Spalink 8184e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin /** 8194e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin * North America Plus Code : 8204e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin * Convert + code to 011 and dial out for international SMS 8214e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin */ 8224e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin CdmaSmsAddress destAddr = CdmaSmsAddress.parse( 8234e4ad34159dc1c720a3e6145bb9f14c60fb1a3f7Soojung Shin PhoneNumberUtils.cdmaCheckAndProcessPlusCode(destAddrStr)); 8248478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink if (destAddr == null) return null; 8258478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8268478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink BearerData bearerData = new BearerData(); 8278478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; 8288478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8291f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink bearerData.messageId = getNextMessageId(); 8308478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8318478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.deliveryAckReq = statusReportRequested; 8328478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.userAckReq = false; 8338478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.readAckReq = false; 8348478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.reportReq = false; 8358478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8368478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink bearerData.userData = userData; 837fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink 8388478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink byte[] encodedBearerData = BearerData.encode(bearerData); 83950f7ea53c3f356453fc4304b911c9a022290d924jsh if (Log.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) { 84049bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData); 84149bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'"); 84249bd918dc26a3a599d8d04212de5600abc3e48c4Tammo Spalink } 8438478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink if (encodedBearerData == null) return null; 8448478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 845079ad20da7df79f26880c9076967dc3fbce6528cTammo Spalink int teleservice = bearerData.hasUserDataHeader ? 846079ad20da7df79f26880c9076967dc3fbce6528cTammo Spalink SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT; 847079ad20da7df79f26880c9076967dc3fbce6528cTammo Spalink 8488478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink SmsEnvelope envelope = new SmsEnvelope(); 8498478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT; 850fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink envelope.teleService = teleservice; 8518478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink envelope.destAddress = destAddr; 8528478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink envelope.bearerReply = RETURN_ACK; 8538478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink envelope.bearerData = encodedBearerData; 8548478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8558478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink /** 8568478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * TODO(cleanup): envelope looks to be a pointless class, get 8578478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * rid of it. Also -- most of the envelope fields set here 8588478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * are ignored, why? 8598478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 860767a662ecde33c3979bf02b793d392aca0403162Wink Saville 861767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 8628478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink /** 8638478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink * TODO(cleanup): reference a spec and get rid of the ugly comments 8648478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink */ 8658478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 8668478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink DataOutputStream dos = new DataOutputStream(baos); 8678478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.writeInt(envelope.teleService); 868767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(0); //servicePresent 869767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(0); //serviceCategory 8708478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.digitMode); 8718478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.numberMode); 8728478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.ton); // number_type 8738478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.numberPlan); 8748478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.numberOfDigits); 8758478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits 876767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Subaddress is not supported. 877767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.write(0); //subaddressType 878767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.write(0); //subaddr_odd 879767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.write(0); //subaddr_nbr_of_digits 8808478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(encodedBearerData.length); 8818478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink dos.write(encodedBearerData, 0, encodedBearerData.length); 882767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.close(); 8838478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink 8848478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink SubmitPdu pdu = new SubmitPdu(); 8858478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink pdu.encodedMessage = baos.toByteArray(); 8868478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink pdu.encodedScAddress = null; 8878478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink return pdu; 888767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch(IOException ex) { 8898478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink Log.e(LOG_TAG, "creating SubmitPdu failed: " + ex); 890767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 8918478b59f177ec97a9996b71f7fac1509ba9ef493Tammo Spalink return null; 892767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 893767a662ecde33c3979bf02b793d392aca0403162Wink Saville 894767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 895767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Creates byte array (pseudo pdu) from SMS object. 896767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Note: Do not call this method more than once per object! 897767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 898767a662ecde33c3979bf02b793d392aca0403162Wink Saville private void createPdu() { 899767a662ecde33c3979bf02b793d392aca0403162Wink Saville SmsEnvelope env = mEnvelope; 900767a662ecde33c3979bf02b793d392aca0403162Wink Saville CdmaSmsAddress addr = env.origAddress; 901767a662ecde33c3979bf02b793d392aca0403162Wink Saville ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 902767a662ecde33c3979bf02b793d392aca0403162Wink Saville DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos)); 903767a662ecde33c3979bf02b793d392aca0403162Wink Saville 904767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 905767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(env.messageType); 906767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(env.teleService); 907767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(env.serviceCategory); 908767a662ecde33c3979bf02b793d392aca0403162Wink Saville 909767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(addr.digitMode); 910767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(addr.numberMode); 911767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(addr.ton); 912767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(addr.numberPlan); 913767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(addr.numberOfDigits); 914767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.write(addr.origBytes, 0, addr.origBytes.length); // digits 915767a662ecde33c3979bf02b793d392aca0403162Wink Saville 916767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeInt(env.bearerReply); 917767a662ecde33c3979bf02b793d392aca0403162Wink Saville // CauseCode values: 918767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(env.replySeqNo); 919767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(env.errorClass); 920767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.writeByte(env.causeCode); 921767a662ecde33c3979bf02b793d392aca0403162Wink Saville //encoded BearerData: 922e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville dos.writeInt(env.bearerData.length); 923767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.write(env.bearerData, 0, env.bearerData.length); 924767a662ecde33c3979bf02b793d392aca0403162Wink Saville dos.close(); 925767a662ecde33c3979bf02b793d392aca0403162Wink Saville 92664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 9275082fd58e33aa54d760459de3368912c37864a4fSatish Roddom * TODO(cleanup) -- The mPdu field is managed in 9285082fd58e33aa54d760459de3368912c37864a4fSatish Roddom * a fragile manner, and it would be much nicer if 92964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * accessing the serialized representation used a less 93064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * fragile mechanism. Maybe the getPdu method could 93164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * generate a representation if there was not yet one? 93264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 93364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 934767a662ecde33c3979bf02b793d392aca0403162Wink Saville mPdu = baos.toByteArray(); 935767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (IOException ex) { 936767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(LOG_TAG, "createPdu: conversion from object to byte array failed: " + ex); 937767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 938767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 939767a662ecde33c3979bf02b793d392aca0403162Wink Saville 940e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville /** 941e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville * Converts a 4-Bit DTMF encoded symbol from the calling address number to ASCII character 942e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville */ 943e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville private byte convertDtmfToAscii(byte dtmfDigit) { 944e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville byte asciiDigit; 945e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 946e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville switch (dtmfDigit) { 947e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 0: asciiDigit = 68; break; // 'D' 948e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 1: asciiDigit = 49; break; // '1' 949e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 2: asciiDigit = 50; break; // '2' 950e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 3: asciiDigit = 51; break; // '3' 951e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 4: asciiDigit = 52; break; // '4' 952e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 5: asciiDigit = 53; break; // '5' 953e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 6: asciiDigit = 54; break; // '6' 954e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 7: asciiDigit = 55; break; // '7' 955e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 8: asciiDigit = 56; break; // '8' 956e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 9: asciiDigit = 57; break; // '9' 957e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 10: asciiDigit = 48; break; // '0' 958e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 11: asciiDigit = 42; break; // '*' 959e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 12: asciiDigit = 35; break; // '#' 960e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 13: asciiDigit = 65; break; // 'A' 961e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 14: asciiDigit = 66; break; // 'B' 962e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville case 15: asciiDigit = 67; break; // 'C' 963e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville default: 964e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville asciiDigit = 32; // Invalid DTMF code 965e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville break; 966e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville } 967e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 968e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville return asciiDigit; 969e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville } 970e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 971ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause /** This function shall be called to get the number of voicemails. 972ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause * @hide 973ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause */ 974ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause /*package*/ int getNumOfVoicemails() { 975ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause return mBearerData.numberOfMessages; 976ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krause } 977e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 9789d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson /** 9799d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson * Returns a byte array that can be use to uniquely identify a received SMS message. 9809d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson * C.S0015-B 4.3.1.6 Unique Message Identification. 9819d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson * 9829d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson * @return byte array uniquely identifying the message. 9839d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson * @hide 9849d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson */ 9859d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson /* package */ byte[] getIncomingSmsFingerprint() { 9869d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson ByteArrayOutputStream output = new ByteArrayOutputStream(); 9879d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 9889d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson output.write(mEnvelope.teleService); 9899d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length); 9909d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length); 9917d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla output.write(mEnvelope.origSubaddress.origBytes, 0, 9927d16427653e047e4901988e7ee04d637e65253b7Naveen Kalla mEnvelope.origSubaddress.origBytes.length); 993e66b5c43cb2d0aece7f4a636a2368a9c66c46cf5Wink Saville 9949d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson return output.toByteArray(); 9959d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson } 9963e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby 9973e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby /** 9983e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby * Returns the list of service category program data, if present. 9993e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby * @return a list of CdmaSmsCbProgramData objects, or null if not present 10003e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby */ 10017b661fb3fc17f981bb122520791344891a3c1661Jake Hamby ArrayList<CdmaSmsCbProgramData> getSmsCbProgramData() { 10023e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby return mBearerData.serviceCategoryProgramData; 10033e3c3f80a90b156ff500076f8655647dfb317acfJake Hamby } 1004767a662ecde33c3979bf02b793d392aca0403162Wink Saville} 1005