10d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/* 20d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Copyright (C) 2013 The Android Open Source Project 30d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 40d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Licensed under the Apache License, Version 2.0 (the "License"); 50d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * you may not use this file except in compliance with the License. 60d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * You may obtain a copy of the License at 70d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 80d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * http://www.apache.org/licenses/LICENSE-2.0 90d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Unless required by applicable law or agreed to in writing, software 110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * distributed under the License is distributed on an "AS IS" BASIS, 120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * See the License for the specific language governing permissions and 140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * limitations under the License. 150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 170d4bcdf379842af4b6304809156971e926f374f0Jake Hambypackage com.android.internal.telephony.cdma; 180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 190d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.app.Activity; 200d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.Context; 210d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.res.Resources; 220d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.os.Message; 230d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.os.SystemProperties; 240d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.provider.Telephony.Sms.Intents; 250d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.telephony.SmsCbMessage; 260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 270d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.CellBroadcastHandler; 280d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.CommandsInterface; 290d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.InboundSmsHandler; 300d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.InboundSmsTracker; 310d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.PhoneBase; 320d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsConstants; 330d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsMessageBase; 340d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.SmsStorageMonitor; 350d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.TelephonyProperties; 360d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.WspTypeDecoder; 370d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 390d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport java.util.Arrays; 400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/** 420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Subclass of {@link InboundSmsHandler} for 3GPP2 type messages. 430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 440d4bcdf379842af4b6304809156971e926f374f0Jake Hambypublic class CdmaInboundSmsHandler extends InboundSmsHandler { 450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final CdmaSMSDispatcher mSmsDispatcher; 470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final CdmaServiceCategoryProgramHandler mServiceCategoryProgramHandler; 480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private byte[] mLastDispatchedSmsFingerprint; 500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private byte[] mLastAcknowledgedSmsFingerprint; 510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( 530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby com.android.internal.R.bool.config_duplicate_port_omadm_wappush); 540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Create a new inbound SMS handler for CDMA. 570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private CdmaInboundSmsHandler(Context context, SmsStorageMonitor storageMonitor, 590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby PhoneBase phone, CdmaSMSDispatcher smsDispatcher) { 60d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville super("CdmaInboundSmsHandler", context, storageMonitor, phone, 61fce951e90d421ba2ab3da3f64d0f5192ab769e22Sukanya Rajkhowa CellBroadcastHandler.makeCellBroadcastHandler(context, phone)); 620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mSmsDispatcher = smsDispatcher; 630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mServiceCategoryProgramHandler = CdmaServiceCategoryProgramHandler.makeScpHandler(context, 640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby phone.mCi); 650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby phone.mCi.setOnNewCdmaSms(getHandler(), EVENT_NEW_SMS, null); 660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Unregister for CDMA SMS. 700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void onQuitting() { 730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mPhone.mCi.unSetOnNewCdmaSms(getHandler()); 740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mCellBroadcastHandler.dispose(); 750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (DBG) log("unregistered for 3GPP2 SMS"); 770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby super.onQuitting(); 780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Wait for state machine to enter startup state. We can't send any messages until then. 820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public static CdmaInboundSmsHandler makeInboundSmsHandler(Context context, 840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby SmsStorageMonitor storageMonitor, PhoneBase phone, CdmaSMSDispatcher smsDispatcher) { 850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby CdmaInboundSmsHandler handler = new CdmaInboundSmsHandler(context, storageMonitor, 860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby phone, smsDispatcher); 870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby handler.start(); 880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return handler; 890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Return whether the device is in Emergency Call Mode (only for 3GPP2). 930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return true if the device is in ECM; false otherwise 940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private static boolean isInEmergencyCallMode() { 960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return "true".equals(inEcm); 980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Return true if this handler is for 3GPP2 messages; false for 3GPP format. 1020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return true (3GPP2) 1030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected boolean is3gpp2() { 1060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return true; 1070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Process Cell Broadcast, Voicemail Notification, and other 3GPP/3GPP2-specific messages. 1110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param smsb the SmsMessageBase object from the RIL 1120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return true if the message was handled here; false to continue processing 1130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected int dispatchMessageRadioSpecific(SmsMessageBase smsb) { 1160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (isInEmergencyCallMode()) { 1170d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Activity.RESULT_OK; 1180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1190d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1200d4bcdf379842af4b6304809156971e926f374f0Jake Hamby SmsMessage sms = (SmsMessage) smsb; 1210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby boolean isBroadcastType = (SmsEnvelope.MESSAGE_TYPE_BROADCAST == sms.getMessageType()); 1220d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Handle CMAS emergency broadcast messages. 1240d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (isBroadcastType) { 1250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("Broadcast type message"); 1260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby SmsCbMessage cbMessage = sms.parseBroadcastSms(); 1270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (cbMessage != null) { 1280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mCellBroadcastHandler.dispatchSmsMessage(cbMessage); 1290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } else { 1300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby loge("error trying to parse broadcast SMS"); 1310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 1330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Initialize fingerprint field, and see if we have a network duplicate SMS. 1360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); 1370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (mLastAcknowledgedSmsFingerprint != null && 1380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { 1390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 1400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Decode BD stream and set sms variables. 1430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sms.parseSms(); 1440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int teleService = sms.getTeleService(); 1450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby switch (teleService) { 1470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_VMN: 1480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_MWI: 1490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // handle voicemail indication 1500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby handleVoicemailTeleservice(sms); 1510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 1520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_WMT: 1540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_WEMT: 1550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (sms.isStatusReportMessage()) { 1560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mSmsDispatcher.sendStatusReportMessage(sms); 1570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 1580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby break; 1600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_SCPT: 1620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mServiceCategoryProgramHandler.dispatchSmsMessage(sms); 1630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 1640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case SmsEnvelope.TELESERVICE_WAP: 1660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // handled below, after storage check 1670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby break; 1680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby default: 1700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby loge("unsupported teleservice 0x" + Integer.toHexString(teleService)); 1710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_UNSUPPORTED; 1720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (!mStorageMonitor.isStorageAvailable() && 1750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sms.getMessageClass() != SmsConstants.MessageClass.CLASS_0) { 1760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // It's a storable message and there's no storage available. Bail. 1770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // (See C.S0015-B v2.0 for a description of "Immediate Display" 1780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // messages, which we represent as CLASS_0.) 1790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_OUT_OF_MEMORY; 1800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (SmsEnvelope.TELESERVICE_WAP == teleService) { 1830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return processCdmaWapPdu(sms.getUserData(), sms.mMessageRef, 1840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sms.getOriginatingAddress(), sms.getTimestampMillis()); 1850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return dispatchNormalMessage(smsb); 1880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Send an acknowledge message. 1920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param success indicates that last message was successfully received. 1930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param result result code indicating any error 1940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param response callback message sent when operation completes. 1950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { 1980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (isInEmergencyCallMode()) { 1990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return; 2000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int causeCode = resultToCause(result); 2030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mPhone.mCi.acknowledgeLastIncomingCdmaSms(success, causeCode, response); 2040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (causeCode == 0) { 2060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; 2070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mLastDispatchedSmsFingerprint = null; 2090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 212d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville * Called when the phone changes the default method updates mPhone 213d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville * mStorageMonitor and mCellBroadcastHandler.updatePhoneObject. 214d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville * Override if different or other behavior is desired. 215d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville * 216d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville * @param phone 217d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville */ 218d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville @Override 219d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville protected void onUpdatePhoneObject(PhoneBase phone) { 220d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville super.onUpdatePhoneObject(phone); 221d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville mCellBroadcastHandler.updatePhoneObject(phone); 222d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 223d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 224d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville /** 2250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Convert Android result code to CDMA SMS failure cause. 2260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param rc the Android SMS intent result value 2270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return 0 for success, or a CDMA SMS failure cause value 2280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private static int resultToCause(int rc) { 2300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby switch (rc) { 2310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case Activity.RESULT_OK: 2320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case Intents.RESULT_SMS_HANDLED: 2330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Cause code is ignored on success. 2340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return 0; 2350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case Intents.RESULT_SMS_OUT_OF_MEMORY: 2360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 2370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case Intents.RESULT_SMS_UNSUPPORTED: 2380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; 2390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case Intents.RESULT_SMS_GENERIC_ERROR: 2400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby default: 2410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; 2420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Handle {@link SmsEnvelope#TELESERVICE_VMN} and {@link SmsEnvelope#TELESERVICE_MWI}. 2470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param sms the message to process 2480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private void handleVoicemailTeleservice(SmsMessage sms) { 2500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int voicemailCount = sms.getNumOfVoicemails(); 2510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (DBG) log("Voicemail count=" + voicemailCount); 2520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 25326a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa // range check 25426a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa if (voicemailCount < 0) { 25526a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa voicemailCount = -1; 25626a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa } else if (voicemailCount > 99) { 25726a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa // C.S0015-B v2, 4.5.12 25826a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa // range: 0-99 25926a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa voicemailCount = 99; 26026a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa } 26126a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa // update voice mail count in phone 26226a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa mPhone.setVoiceMessageCount(voicemailCount); 26326a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa // store voice mail count in preferences 26426a4150cfb8cd317eb64994b9d9fd6109bd87ba7Sukanya Rajkhowa storeVoiceMailCount(); 2650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Processes inbound messages that are in the WAP-WDP PDU format. See 2690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 2700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * WDP segments are gathered until a datagram completes and gets dispatched. 2710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 2720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param pdu The WAP-WDP PDU segment 2730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return a result code from {@link android.provider.Telephony.Sms.Intents}, or 2740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * {@link Activity#RESULT_OK} if the message has been broadcast 2750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * to applications 2760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address, 2780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby long timestamp) { 2790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int index = 0; 2800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int msgType = (0xFF & pdu[index++]); 2820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (msgType != 0) { 2830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("Received a WAP SMS which is not WDP. Discard."); 2840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 2850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int totalSegments = (0xFF & pdu[index++]); // >= 1 2870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int segment = (0xFF & pdu[index++]); // >= 0 2880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (segment >= totalSegments) { 2900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby loge("WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1)); 2910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return Intents.RESULT_SMS_HANDLED; 2920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Only the first segment contains sourcePort and destination Port 2950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int sourcePort = 0; 2960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int destinationPort = 0; 2970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (segment == 0) { 2980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby //process WDP segment 2990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sourcePort = (0xFF & pdu[index++]) << 8; 3000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sourcePort |= 0xFF & pdu[index++]; 3010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby destinationPort = (0xFF & pdu[index++]) << 8; 3020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby destinationPort |= 0xFF & pdu[index++]; 3030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Some carriers incorrectly send duplicate port fields in omadm wap pushes. 3040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // If configured, check for that here 3050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (mCheckForDuplicatePortsInOmadmWapPush) { 3060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (checkDuplicatePortOmadmWapPush(pdu, index)) { 3070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby index = index + 4; // skip duplicate port fields 3080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Lookup all other related parts 3130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("Received WAP PDU. Type = " + msgType + ", originator = " + address 3140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 3150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments); 3160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3170d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // pass the user data portion of the PDU to the shared handler in SMSDispatcher 3180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby byte[] userData = new byte[pdu.length - index]; 3190d4bcdf379842af4b6304809156971e926f374f0Jake Hamby System.arraycopy(pdu, index, userData, 0, pdu.length - index); 3200d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby InboundSmsTracker tracker = new InboundSmsTracker(userData, timestamp, destinationPort, 3228b61e10b480d3a7bae41025a97f3bd27ee5ed610Jake Hamby true, address, referenceNumber, segment, totalSegments, true); 3230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3240d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return addTrackerToRawTableAndSendMessage(tracker); 3250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 3280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Optional check to see if the received WapPush is an OMADM notification with erroneous 3290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * extra port fields. 3300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * - Some carriers make this mistake. 3310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * ex: MSGTYPE-TotalSegments-CurrentSegment 3320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * -SourcePortDestPort-SourcePortDestPort-OMADM PDU 3330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param origPdu The WAP-WDP PDU segment 3340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param index Current Index while parsing the PDU. 3350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. 3360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. 3370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 3380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private static boolean checkDuplicatePortOmadmWapPush(byte[] origPdu, int index) { 3390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby index += 4; 3400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby byte[] omaPdu = new byte[origPdu.length - index]; 3410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); 3420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); 3440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby int wspIndex = 2; 3450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Process header length field 3470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (!pduDecoder.decodeUintvarInteger(wspIndex)) { 3480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return false; 3490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field 3520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // Process content type field 3540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (!pduDecoder.decodeContentType(wspIndex)) { 3550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return false; 3560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 3580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby String mimeType = pduDecoder.getValueString(); 3590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return (WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI.equals(mimeType)); 3600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 3610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby} 362