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