1767a662ecde33c3979bf02b793d392aca0403162Wink Saville/* 2767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Copyright (C) 2008 The Android Open Source Project 3767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 4767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5767a662ecde33c3979bf02b793d392aca0403162Wink Saville * you may not use this file except in compliance with the License. 6767a662ecde33c3979bf02b793d392aca0403162Wink Saville * You may obtain a copy of the License at 7767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 8767a662ecde33c3979bf02b793d392aca0403162Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 9767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 10767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Unless required by applicable law or agreed to in writing, software 11767a662ecde33c3979bf02b793d392aca0403162Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13767a662ecde33c3979bf02b793d392aca0403162Wink Saville * See the License for the specific language governing permissions and 14767a662ecde33c3979bf02b793d392aca0403162Wink Saville * limitations under the License. 15767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 16767a662ecde33c3979bf02b793d392aca0403162Wink Saville 17767a662ecde33c3979bf02b793d392aca0403162Wink Savillepackage com.android.internal.telephony.cdma; 18767a662ecde33c3979bf02b793d392aca0403162Wink Saville 19767a662ecde33c3979bf02b793d392aca0403162Wink Saville 20867641ece36e2fd17faaea79cf19506ab17177c6jshimport android.app.Activity; 21767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.app.PendingIntent; 22a1c94ae4f75dab030219069864029f5bd9498fb0Richard Mengimport android.app.PendingIntent.CanceledException; 23767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.content.ContentValues; 24d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalinkimport android.content.Intent; 25ce099c3226b33b43e0dd5d1f24347b14a2223ee1David Krauseimport android.content.SharedPreferences; 26767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.database.Cursor; 27767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.database.SQLException; 28767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Message; 29117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yangimport android.os.SystemProperties; 30059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport android.preference.PreferenceManager; 313960ced4638fdb24ddf904fcb6734dae0959671ejshimport android.provider.Telephony; 32867641ece36e2fd17faaea79cf19506ab17177c6jshimport android.provider.Telephony.Sms.Intents; 33a1c94ae4f75dab030219069864029f5bd9498fb0Richard Mengimport android.telephony.SmsManager; 34a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jshimport android.telephony.SmsMessage.MessageClass; 35059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport android.util.Log; 36767a662ecde33c3979bf02b793d392aca0403162Wink Saville 37867641ece36e2fd17faaea79cf19506ab17177c6jshimport com.android.internal.telephony.CommandsInterface; 38059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport com.android.internal.telephony.SMSDispatcher; 39767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsHeader; 40767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 411fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscqimport com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; 42b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hambyimport com.android.internal.telephony.SmsStorageMonitor; 43b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hambyimport com.android.internal.telephony.SmsUsageMonitor; 44059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport com.android.internal.telephony.TelephonyProperties; 45d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shinimport com.android.internal.telephony.WspTypeDecoder; 46767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.cdma.sms.SmsEnvelope; 47fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalinkimport com.android.internal.telephony.cdma.sms.UserData; 48767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.util.HexDump; 49767a662ecde33c3979bf02b793d392aca0403162Wink Saville 50767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.io.ByteArrayOutputStream; 519d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafssonimport java.util.Arrays; 52767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.HashMap; 53767a662ecde33c3979bf02b793d392aca0403162Wink Saville 54d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shinimport android.content.res.Resources; 55d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 56767a662ecde33c3979bf02b793d392aca0403162Wink Saville 57767a662ecde33c3979bf02b793d392aca0403162Wink Savillefinal class CdmaSMSDispatcher extends SMSDispatcher { 58767a662ecde33c3979bf02b793d392aca0403162Wink Saville private static final String TAG = "CDMA"; 59767a662ecde33c3979bf02b793d392aca0403162Wink Saville 609d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson private byte[] mLastDispatchedSmsFingerprint; 619d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson private byte[] mLastAcknowledgedSmsFingerprint; 629d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 63b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( 64d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin com.android.internal.R.bool.config_duplicate_port_omadm_wappush); 65d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 66b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor, 67b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby SmsUsageMonitor usageMonitor) { 68b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby super(phone, storageMonitor, usageMonitor); 69b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mCm.setOnNewCdmaSms(this, EVENT_NEW_SMS, null); 70b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } 71b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby 72b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby @Override 73b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby public void dispose() { 74b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mCm.unSetOnNewCdmaSms(this); 75767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 76767a662ecde33c3979bf02b793d392aca0403162Wink Saville 77145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 78b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected String getFormat() { 79b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return android.telephony.SmsMessage.FORMAT_3GPP2; 80767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 81767a662ecde33c3979bf02b793d392aca0403162Wink Saville 82d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink private void handleCdmaStatusReport(SmsMessage sms) { 83d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { 84d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink SmsTracker tracker = deliveryPendingList.get(i); 85d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink if (tracker.mMessageRef == sms.messageRef) { 86d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // Found it. Remove from list and broadcast. 87d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink deliveryPendingList.remove(i); 88d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink PendingIntent intent = tracker.mDeliveryIntent; 89d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink Intent fillIn = new Intent(); 90d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink fillIn.putExtra("pdu", sms.getPdu()); 9132319dd852709b975e53360f479634e43db4d224Jake Hamby fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2); 92d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink try { 93d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink intent.send(mContext, Activity.RESULT_OK, fillIn); 94d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } catch (CanceledException ex) {} 95d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink break; // Only expect to see one tracker matching this message. 96d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 97d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 98d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 99d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink 1003960ced4638fdb24ddf904fcb6734dae0959671ejsh /** {@inheritDoc} */ 101145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 1022b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville public int dispatchMessage(SmsMessageBase smsb) { 103767a662ecde33c3979bf02b793d392aca0403162Wink Saville 104767a662ecde33c3979bf02b793d392aca0403162Wink Saville // If sms is null, means there was a parsing error. 105767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (smsb == null) { 1064219797afc2f5369c27cf7be752e9bc3bdb8057djsh Log.e(TAG, "dispatchMessage: message is null"); 1073960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_GENERIC_ERROR; 108767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 109767a662ecde33c3979bf02b793d392aca0403162Wink Saville 110117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 111117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang if (inEcm.equals("true")) { 112ea803b8e0cc613309d0ce096df9c13e9690243ffSatish Roddom return Activity.RESULT_OK; 113117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang } 114117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 115cde0233512f8dbbc62238e90c850c310894e3972Wink Saville if (mSmsReceiveDisabled) { 116cde0233512f8dbbc62238e90c850c310894e3972Wink Saville // Device doesn't support receiving SMS, 117c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang Log.d(TAG, "Received short message on device which doesn't support " 118cde0233512f8dbbc62238e90c850c310894e3972Wink Saville + "receiving SMS. Ignored."); 119c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang return Intents.RESULT_SMS_HANDLED; 120c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang } 121c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang 1229d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // See if we have a network duplicate SMS. 12364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsMessage sms = (SmsMessage) smsb; 1249d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); 1259d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson if (mLastAcknowledgedSmsFingerprint != null && 1269d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { 1279d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson return Intents.RESULT_SMS_HANDLED; 1289d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson } 1299d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // Decode BD stream and set sms variables. 130767a662ecde33c3979bf02b793d392aca0403162Wink Saville sms.parseSms(); 13164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int teleService = sms.getTeleService(); 13264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink boolean handled = false; 133767a662ecde33c3979bf02b793d392aca0403162Wink Saville 134a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh if ((SmsEnvelope.TELESERVICE_VMN == teleService) || 135a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh (SmsEnvelope.TELESERVICE_MWI == teleService)) { 136a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // handling Voicemail 137a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh int voicemailCount = sms.getNumOfVoicemails(); 138a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh Log.d(TAG, "Voicemail count=" + voicemailCount); 139a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // Store the voicemail count in preferences. 140a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( 141b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mContext); 142a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences.Editor editor = sp.edit(); 143a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); 144fa8e271636b9e9b86f247cdb4c91d9ebe9675c27Brad Fitzpatrick editor.apply(); 145b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mPhone.setVoiceMessageWaiting(1, voicemailCount); 146a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh handled = true; 147d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) || 148d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink (SmsEnvelope.TELESERVICE_WEMT == teleService)) && 149d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink sms.isStatusReportMessage()) { 150d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handleCdmaStatusReport(sms); 151d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handled = true; 152a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } else if ((sms.getUserData() == null)) { 15343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) { 154767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "Received SMS without user data"); 155767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 15664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled = true; 157767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 158767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1593960ced4638fdb24ddf904fcb6734dae0959671ejsh if (handled) { 1603960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 1613960ced4638fdb24ddf904fcb6734dae0959671ejsh } 162767a662ecde33c3979bf02b793d392aca0403162Wink Saville 163b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (!mStorageMonitor.isStorageAvailable() && 164b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby sms.getMessageClass() != MessageClass.CLASS_0) { 165a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // It's a storable message and there's no storage available. Bail. 166a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // (See C.S0015-B v2.0 for a description of "Immediate Display" 167a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // messages, which we represent as CLASS_0.) 168a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh return Intents.RESULT_SMS_OUT_OF_MEMORY; 169a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } 170a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh 171c84401fb8b3ed90039bd132b343852303ef88ce6yong liu if (SmsEnvelope.TELESERVICE_WAP == teleService) { 1723960ced4638fdb24ddf904fcb6734dae0959671ejsh return processCdmaWapPdu(sms.getUserData(), sms.messageRef, 1733960ced4638fdb24ddf904fcb6734dae0959671ejsh sms.getOriginatingAddress()); 174767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 175767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1767e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Reject (NAK) any messages with teleservice ids that have 1777e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // not yet been handled and also do not correspond to the two 1787e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // kinds that are processed below. 1797e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink if ((SmsEnvelope.TELESERVICE_WMT != teleService) && 18083fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.TELESERVICE_WEMT != teleService) && 18183fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) { 1827e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return Intents.RESULT_SMS_UNSUPPORTED; 1837e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink } 1847e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink 185b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return dispatchNormalMessage(smsb); 186767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 187767a662ecde33c3979bf02b793d392aca0403162Wink Saville 188767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 189767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Processes inbound messages that are in the WAP-WDP PDU format. See 190767a662ecde33c3979bf02b793d392aca0403162Wink Saville * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 191767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WDP segments are gathered until a datagram completes and gets dispatched. 192767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 193767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param pdu The WAP-WDP PDU segment 1943960ced4638fdb24ddf904fcb6734dae0959671ejsh * @return a result code from {@link Telephony.Sms.Intents}, or 1953960ced4638fdb24ddf904fcb6734dae0959671ejsh * {@link Activity#RESULT_OK} if the message has been broadcast 1963960ced4638fdb24ddf904fcb6734dae0959671ejsh * to applications 197767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 1983960ced4638fdb24ddf904fcb6734dae0959671ejsh protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { 199767a662ecde33c3979bf02b793d392aca0403162Wink Saville int index = 0; 200767a662ecde33c3979bf02b793d392aca0403162Wink Saville 201929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby int msgType = (0xFF & pdu[index++]); 202b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (msgType != 0) { 203767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(TAG, "Received a WAP SMS which is not WDP. Discard."); 2043960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 205767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 206929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby int totalSegments = (0xFF & pdu[index++]); // >= 1 207929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby int segment = (0xFF & pdu[index++]); // >= 0 208929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby 209929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby if (segment >= totalSegments) { 210929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby Log.e(TAG, "WDP bad segment #" + segment + " expecting 0-" + (totalSegments - 1)); 211929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby return Intents.RESULT_SMS_HANDLED; 212929ca5e49760c3d5af8c7455cd38e29336b5e262Jake Hamby } 213767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2145c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause // Only the first segment contains sourcePort and destination Port 215b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int sourcePort = 0; 216b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int destinationPort = 0; 2175c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause if (segment == 0) { 2185c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause //process WDP segment 2195c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort = (0xFF & pdu[index++]) << 8; 2205c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort |= 0xFF & pdu[index++]; 2215c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort = (0xFF & pdu[index++]) << 8; 2225c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort |= 0xFF & pdu[index++]; 223d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Some carriers incorrectly send duplicate port fields in omadm wap pushes. 224d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // If configured, check for that here 225d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (mCheckForDuplicatePortsInOmadmWapPush) { 226d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (checkDuplicatePortOmadmWappush(pdu,index)) { 227d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index = index + 4; // skip duplicate port fields 228d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 229d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 2305c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause } 231767a662ecde33c3979bf02b793d392aca0403162Wink Saville 232767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Lookup all other related parts 233767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address 234767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 235b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments); 236767a662ecde33c3979bf02b793d392aca0403162Wink Saville 237b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby // pass the user data portion of the PDU to the shared handler in SMSDispatcher 238b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby byte[] userData = new byte[pdu.length - index]; 239b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby System.arraycopy(pdu, index, userData, 0, pdu.length - index); 240767a662ecde33c3979bf02b793d392aca0403162Wink Saville 241b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return processMessagePart(userData, address, referenceNumber, segment, totalSegments, 242b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby 0L, destinationPort, true); 243767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 244767a662ecde33c3979bf02b793d392aca0403162Wink Saville 245767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 246145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 2471f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendData(String destAddr, String scAddr, int destPort, 2481f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 2491f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 2501f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, destPort, data, (deliveryIntent != null)); 2511f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 2521f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 2531f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 2541f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 255145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 2561f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendText(String destAddr, String scAddr, String text, 2571f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 2581f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 2591f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, text, (deliveryIntent != null), null); 2601f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 2611f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 2621f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 2631f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 264145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 265b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected TextEncodingDetails calculateLength(CharSequence messageBody, 266b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby boolean use7bitOnly) { 267b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return SmsMessage.calculateLength(messageBody, use7bitOnly); 268b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } 269767a662ecde33c3979bf02b793d392aca0403162Wink Saville 270b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby /** {@inheritDoc} */ 271b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby @Override 272b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected void sendNewSubmitPdu(String destinationAddress, String scAddress, 273b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby String message, SmsHeader smsHeader, int encoding, 274b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { 275b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby UserData uData = new UserData(); 276b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.payloadStr = message; 277b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.userDataHeader = smsHeader; 278b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) { 279b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; 280b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } else { // assume UTF-16 281b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncoding = UserData.ENCODING_UNICODE_16; 282b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } 283b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncodingSet = true; 284fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink 285b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby /* By setting the statusReportRequested bit only for the 286b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * last message fragment, this will result in only one 287b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * callback to the sender when that last fragment delivery 288b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * has been acknowledged. */ 289b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress, 290b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData, (deliveryIntent != null) && lastPart); 291767a662ecde33c3979bf02b793d392aca0403162Wink Saville 292b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); 293767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 294767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2951f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, 2961f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 2971f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { 298a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng if (sentIntent != null) { 299a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng try { 300a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); 301a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } catch (CanceledException ex) {} 302a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 30343a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) { 304a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng Log.d(TAG, "Block SMS in Emergency Callback mode"); 305a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 306a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng return; 307a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 3081f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); 309a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 310a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng 311767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 312145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 313767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendSms(SmsTracker tracker) { 314145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby HashMap<String, Object> map = tracker.mData; 315767a662ecde33c3979bf02b793d392aca0403162Wink Saville 316059fe88115ccb70d9870698e490ed5b4c88da50cJake Hamby // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA 317767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte pdu[] = (byte[]) map.get("pdu"); 318767a662ecde33c3979bf02b793d392aca0403162Wink Saville 319767a662ecde33c3979bf02b793d392aca0403162Wink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 320767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.sendCdmaSms(pdu, reply); 321767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 322767a662ecde33c3979bf02b793d392aca0403162Wink Saville 323767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 324145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 325b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { 326117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 327117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang if (inEcm.equals("true")) { 328117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang return; 329117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang } 330117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 331b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int causeCode = resultToCause(result); 332b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response); 3339d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 334b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (causeCode == 0) { 335b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; 336767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 337b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mLastDispatchedSmsFingerprint = null; 338767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 339767a662ecde33c3979bf02b793d392aca0403162Wink Saville 340b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby private static int resultToCause(int rc) { 341867641ece36e2fd17faaea79cf19506ab17177c6jsh switch (rc) { 3427e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Activity.RESULT_OK: 3437e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_HANDLED: 3447e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Cause code is ignored on success. 3457e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return 0; 3467e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_OUT_OF_MEMORY: 3477e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 3487e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_UNSUPPORTED: 3497e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; 3507e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_GENERIC_ERROR: 3517e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink default: 3523ff560d7ba9fcedc4d388f63b756108a715266f4jsh return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; 353867641ece36e2fd17faaea79cf19506ab17177c6jsh } 354867641ece36e2fd17faaea79cf19506ab17177c6jsh } 355d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 356d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin /** 357d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * Optional check to see if the received WapPush is an OMADM notification with erroneous 358d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * extra port fields. 359d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * - Some carriers make this mistake. 360d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * ex: MSGTYPE-TotalSegments-CurrentSegment 361d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * -SourcePortDestPort-SourcePortDestPort-OMADM PDU 362d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param origPdu The WAP-WDP PDU segment 363d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param index Current Index while parsing the PDU. 364d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. 365d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. 366d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin */ 367b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { 368d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index += 4; 369d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin byte[] omaPdu = new byte[origPdu.length - index]; 370d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); 371d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 372d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); 373d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin int wspIndex = 2; 374d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 375d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process header length field 376d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { 377d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 378d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 379d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 380d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field 381d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 382d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process content type field 383d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeContentType(wspIndex) == false) { 384d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 385d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 386d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 387d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin String mimeType = pduDecoder.getValueString(); 388d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { 389d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen return true; 390d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 391d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 392d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 393767a662ecde33c3979bf02b793d392aca0403162Wink Saville} 394