CdmaSMSDispatcher.java revision 22d85a8e3a575a6d01d2c788587971657dfe20c6
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 Saville 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.Activity; 217fce994eb223105829becb6c26e3af7a9739752cDianne Hackbornimport android.app.AppOpsManager; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent; 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.PendingIntent.CanceledException; 24b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.content.BroadcastReceiver; 25b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.content.Context; 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Intent; 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.SharedPreferences; 28b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.content.res.Resources; 29b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.os.Bundle; 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.Message; 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties; 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.preference.PreferenceManager; 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.provider.Telephony.Sms.Intents; 34b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.telephony.PhoneNumberUtils; 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsCbMessage; 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.SmsManager; 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.telephony.cdma.CdmaSmsCbProgramData; 38b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport android.telephony.cdma.CdmaSmsCbProgramResults; 3999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Savilleimport android.telephony.Rlog; 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.CommandsInterface; 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet; 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsConstants; 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SMSDispatcher; 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsHeader; 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsStorageMonitor; 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.SmsUsageMonitor; 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.TelephonyProperties; 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.WspTypeDecoder; 51b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport com.android.internal.telephony.cdma.sms.BearerData; 52b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport com.android.internal.telephony.cdma.sms.CdmaSmsAddress; 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.cdma.sms.UserData; 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.io.ByteArrayOutputStream; 57b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport java.io.DataOutputStream; 58b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport java.io.IOException; 59b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hambyimport java.util.ArrayList; 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Arrays; 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.HashMap; 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillefinal class CdmaSMSDispatcher extends SMSDispatcher { 65cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final String TAG = "CdmaSMSDispatcher"; 66cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville private static final boolean VDBG = false; 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private byte[] mLastDispatchedSmsFingerprint; 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private byte[] mLastAcknowledgedSmsFingerprint; 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville com.android.internal.R.bool.config_duplicate_port_omadm_wappush); 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor, 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsUsageMonitor usageMonitor) { 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville super(phone, storageMonitor, usageMonitor); 7722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.setOnNewCdmaSms(this, EVENT_NEW_SMS, null); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void dispose() { 8222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.unSetOnNewCdmaSms(this); 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected String getFormat() { 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return android.telephony.SmsMessage.FORMAT_3GPP2; 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleCdmaStatusReport(SmsMessage sms) { 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsTracker tracker = deliveryPendingList.get(i); 9322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville if (tracker.mMessageRef == sms.mMessageRef) { 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Found it. Remove from list and broadcast. 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville deliveryPendingList.remove(i); 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PendingIntent intent = tracker.mDeliveryIntent; 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Intent fillIn = new Intent(); 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville fillIn.putExtra("pdu", sms.getPdu()); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2); 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville intent.send(mContext, Activity.RESULT_OK, fillIn); 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CanceledException ex) {} 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; // Only expect to see one tracker matching this message. 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Dispatch service category program data to the CellBroadcastReceiver app, which filters 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the broadcast alerts to display. 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param sms the SMS message containing one or more 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link android.telephony.cdma.CdmaSmsCbProgramData} objects. 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void handleServiceCategoryProgramData(SmsMessage sms) { 115b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby ArrayList<CdmaSmsCbProgramData> programDataList = sms.getSmsCbProgramData(); 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (programDataList == null) { 11799c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "handleServiceCategoryProgramData: program data list is null!"); 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Intent intent = new Intent(Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION); 122b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby intent.putExtra("sender", sms.getOriginatingAddress()); 123b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby intent.putParcelableArrayListExtra("program_data", programDataList); 1247fce994eb223105829becb6c26e3af7a9739752cDianne Hackborn dispatch(intent, RECEIVE_SMS_PERMISSION, AppOpsManager.OP_RECEIVE_SMS, mScpResultsReceiver); 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int dispatchMessage(SmsMessageBase smsb) { 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If sms is null, means there was a parsing error. 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (smsb == null) { 13399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "dispatchMessage: message is null"); 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_GENERIC_ERROR; 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (inEcm.equals("true")) { 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Activity.RESULT_OK; 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mSmsReceiveDisabled) { 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Device doesn't support receiving SMS, 14499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(TAG, "Received short message on device which doesn't support " 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + "receiving SMS. Ignored."); 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage sms = (SmsMessage) smsb; 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Handle CMAS emergency broadcast messages. 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType()) { 15399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(TAG, "Broadcast type message"); 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsCbMessage message = sms.parseBroadcastSms(); 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (message != null) { 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dispatchBroadcastMessage(message); 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // See if we have a network duplicate SMS. 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mLastAcknowledgedSmsFingerprint != null && 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Decode BD stream and set sms variables. 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms.parseSms(); 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int teleService = sms.getTeleService(); 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean handled = false; 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((SmsEnvelope.TELESERVICE_VMN == teleService) || 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (SmsEnvelope.TELESERVICE_MWI == teleService)) { 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // handling Voicemail 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int voicemailCount = sms.getNumOfVoicemails(); 17699c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(TAG, "Voicemail count=" + voicemailCount); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Store the voicemail count in preferences. 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mContext); 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SharedPreferences.Editor editor = sp.edit(); 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville editor.apply(); 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mPhone.setVoiceMessageWaiting(1, voicemailCount); 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handled = true; 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) || 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (SmsEnvelope.TELESERVICE_WEMT == teleService)) && 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms.isStatusReportMessage()) { 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleCdmaStatusReport(sms); 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handled = true; 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (SmsEnvelope.TELESERVICE_SCPT == teleService) { 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handleServiceCategoryProgramData(sms); 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handled = true; 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if ((sms.getUserData() == null)) { 194cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) { 19599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(TAG, "Received SMS without user data"); 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville handled = true; 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (handled) { 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!mStorageMonitor.isStorageAvailable() && 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms.getMessageClass() != SmsConstants.MessageClass.CLASS_0) { 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // It's a storable message and there's no storage available. Bail. 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // (See C.S0015-B v2.0 for a description of "Immediate Display" 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // messages, which we represent as CLASS_0.) 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_OUT_OF_MEMORY; 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SmsEnvelope.TELESERVICE_WAP == teleService) { 21322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville return processCdmaWapPdu(sms.getUserData(), sms.mMessageRef, 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sms.getOriginatingAddress()); 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Reject (NAK) any messages with teleservice ids that have 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // not yet been handled and also do not correspond to the two 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // kinds that are processed below. 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((SmsEnvelope.TELESERVICE_WMT != teleService) && 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (SmsEnvelope.TELESERVICE_WEMT != teleService) && 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) { 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_UNSUPPORTED; 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return dispatchNormalMessage(smsb); 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Processes inbound messages that are in the WAP-WDP PDU format. See 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WDP segments are gathered until a datagram completes and gets dispatched. 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param pdu The WAP-WDP PDU segment 235cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville * @return a result code from {@link android.provider.Telephony.Sms.Intents}, or 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@link Activity#RESULT_OK} if the message has been broadcast 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * to applications 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int index = 0; 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int msgType = (0xFF & pdu[index++]); 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (msgType != 0) { 24499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.w(TAG, "Received a WAP SMS which is not WDP. Discard."); 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int totalSegments = (0xFF & pdu[index++]); // >= 1 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int segment = (0xFF & pdu[index++]); // >= 0 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (segment >= totalSegments) { 25199c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1)); 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return Intents.RESULT_SMS_HANDLED; 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Only the first segment contains sourcePort and destination Port 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int sourcePort = 0; 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int destinationPort = 0; 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (segment == 0) { 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville //process WDP segment 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sourcePort = (0xFF & pdu[index++]) << 8; 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sourcePort |= 0xFF & pdu[index++]; 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville destinationPort = (0xFF & pdu[index++]) << 8; 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville destinationPort |= 0xFF & pdu[index++]; 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Some carriers incorrectly send duplicate port fields in omadm wap pushes. 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // If configured, check for that here 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCheckForDuplicatePortsInOmadmWapPush) { 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (checkDuplicatePortOmadmWappush(pdu,index)) { 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index = index + 4; // skip duplicate port fields 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Lookup all other related parts 27499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments); 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // pass the user data portion of the PDU to the shared handler in SMSDispatcher 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] userData = new byte[pdu.length - index]; 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(pdu, index, userData, 0, pdu.length - index); 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return processMessagePart(userData, address, referenceNumber, segment, totalSegments, 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 0L, destinationPort, true); 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void sendData(String destAddr, String scAddr, int destPort, 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville scAddr, destAddr, destPort, data, (deliveryIntent != null)); 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr); 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void sendText(String destAddr, String scAddr, String text, 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PendingIntent sentIntent, PendingIntent deliveryIntent) { 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville scAddr, destAddr, text, (deliveryIntent != null), null); 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendSubmitPdu(pdu, sentIntent, deliveryIntent, destAddr); 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected GsmAlphabet.TextEncodingDetails calculateLength(CharSequence messageBody, 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean use7bitOnly) { 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return SmsMessage.calculateLength(messageBody, use7bitOnly); 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void sendNewSubmitPdu(String destinationAddress, String scAddress, 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String message, SmsHeader smsHeader, int encoding, 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville UserData uData = new UserData(); 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.payloadStr = message; 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.userDataHeader = smsHeader; 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (encoding == SmsConstants.ENCODING_7BIT) { 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { // assume UTF-16 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncoding = UserData.ENCODING_UNICODE_16; 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData.msgEncodingSet = true; 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /* By setting the statusReportRequested bit only for the 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * last message fragment, this will result in only one 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * callback to the sender when that last fragment delivery 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * has been acknowledged. */ 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress, 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uData, (deliveryIntent != null) && lastPart); 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendSubmitPdu(submitPdu, sentIntent, deliveryIntent, destinationAddress); 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville PendingIntent sentIntent, PendingIntent deliveryIntent, String destAddr) { 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sentIntent != null) { 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (CanceledException ex) {} 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 344cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville if (VDBG) { 34599c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.d(TAG, "Block SMS in Emergency Callback mode"); 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent, destAddr); 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void sendSms(SmsTracker tracker) { 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville HashMap<String, Object> map = tracker.mData; 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte pdu[] = (byte[]) map.get("pdu"); 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 36122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.sendCdmaSms(pdu, reply); 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** {@inheritDoc} */ 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville @Override 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (inEcm.equals("true")) { 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return; 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int causeCode = resultToCause(result); 37322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.acknowledgeLastIncomingCdmaSms(success, causeCode, response); 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (causeCode == 0) { 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLastDispatchedSmsFingerprint = null; 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static int resultToCause(int rc) { 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville switch (rc) { 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case Activity.RESULT_OK: 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case Intents.RESULT_SMS_HANDLED: 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Cause code is ignored on success. 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case Intents.RESULT_SMS_OUT_OF_MEMORY: 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case Intents.RESULT_SMS_UNSUPPORTED: 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville case Intents.RESULT_SMS_GENERIC_ERROR: 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville default: 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Optional check to see if the received WapPush is an OMADM notification with erroneous 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * extra port fields. 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * - Some carriers make this mistake. 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * ex: MSGTYPE-TotalSegments-CurrentSegment 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * -SourcePortDestPort-SourcePortDestPort-OMADM PDU 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param origPdu The WAP-WDP PDU segment 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param index Current Index while parsing the PDU. 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index += 4; 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville byte[] omaPdu = new byte[origPdu.length - index]; 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int wspIndex = 2; 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Process header length field 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Process content type field 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (pduDecoder.decodeContentType(wspIndex) == false) { 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String mimeType = pduDecoder.getValueString(); 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 434b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby 435b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby // Receiver for Service Category Program Data results. 436b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby // We already ACK'd the original SCPD SMS, so this sends a new response SMS. 437b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby // TODO: handle retries if the RIL returns an error. 438b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby private final BroadcastReceiver mScpResultsReceiver = new BroadcastReceiver() { 439b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby @Override 440b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby public void onReceive(Context context, Intent intent) { 441b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby int rc = getResultCode(); 442b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED); 443b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby if (!success) { 44499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "SCP results error: result code = " + rc); 445b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby return; 446b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 447b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby Bundle extras = getResultExtras(false); 448b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby if (extras == null) { 44999c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "SCP results error: missing extras"); 450b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby return; 451b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 452b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby String sender = extras.getString("sender"); 453b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby if (sender == null) { 45499c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "SCP results error: missing sender extra."); 455b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby return; 456b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 457b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby ArrayList<CdmaSmsCbProgramResults> results 458b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby = extras.getParcelableArrayList("results"); 459b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby if (results == null) { 46099c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "SCP results error: missing results extra."); 461b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby return; 462b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 463b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby 464b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby BearerData bData = new BearerData(); 465b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby bData.messageType = BearerData.MESSAGE_TYPE_SUBMIT; 466b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby bData.messageId = SmsMessage.getNextMessageId(); 467b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby bData.serviceCategoryProgramResults = results; 468b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby byte[] encodedBearerData = BearerData.encode(bData); 469b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby 470b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby ByteArrayOutputStream baos = new ByteArrayOutputStream(100); 471b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby DataOutputStream dos = new DataOutputStream(baos); 472b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby try { 473b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.writeInt(SmsEnvelope.TELESERVICE_SCPT); 474b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.writeInt(0); //servicePresent 475b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.writeInt(0); //serviceCategory 476b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby CdmaSmsAddress destAddr = CdmaSmsAddress.parse( 477b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby PhoneNumberUtils.cdmaCheckAndProcessPlusCode(sender)); 478b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.digitMode); 479b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.numberMode); 480b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.ton); // number_type 481b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.numberPlan); 482b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.numberOfDigits); 483b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(destAddr.origBytes, 0, destAddr.origBytes.length); // digits 484b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby // Subaddress is not supported. 485b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(0); //subaddressType 486b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(0); //subaddr_odd 487b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(0); //subaddr_nbr_of_digits 488b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(encodedBearerData.length); 489b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.write(encodedBearerData, 0, encodedBearerData.length); 490b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby // Ignore the RIL response. TODO: implement retry if SMS send fails. 49122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville mCi.sendCdmaSms(baos.toByteArray(), null); 492b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } catch (IOException e) { 49399c2e1d6749cfad2a8ca94a47857d8c3bfc09454Wink Saville Rlog.e(TAG, "exception creating SCP results PDU", e); 494b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } finally { 495b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby try { 496b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby dos.close(); 497b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } catch (IOException ignored) { 498b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 499b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 500b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby } 501b8a13d300b245e0080aa01275e232f54d5d0e09cJake Hamby }; 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 503