CdmaSMSDispatcher.java revision b7945cae5ad0feaad09378d0db77f2b3105e5235
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()); 91d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink try { 92d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink intent.send(mContext, Activity.RESULT_OK, fillIn); 93d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } catch (CanceledException ex) {} 94d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink break; // Only expect to see one tracker matching this message. 95d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 96d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 97d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } 98d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink 993960ced4638fdb24ddf904fcb6734dae0959671ejsh /** {@inheritDoc} */ 100145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 1012b8bcfe5b74e1a34d136f4ff46e3c94397f38f82Wink Saville public int dispatchMessage(SmsMessageBase smsb) { 102767a662ecde33c3979bf02b793d392aca0403162Wink Saville 103767a662ecde33c3979bf02b793d392aca0403162Wink Saville // If sms is null, means there was a parsing error. 104767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (smsb == null) { 1054219797afc2f5369c27cf7be752e9bc3bdb8057djsh Log.e(TAG, "dispatchMessage: message is null"); 1063960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_GENERIC_ERROR; 107767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 108767a662ecde33c3979bf02b793d392aca0403162Wink Saville 109117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 110117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang if (inEcm.equals("true")) { 111ea803b8e0cc613309d0ce096df9c13e9690243ffSatish Roddom return Activity.RESULT_OK; 112117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang } 113117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 114cde0233512f8dbbc62238e90c850c310894e3972Wink Saville if (mSmsReceiveDisabled) { 115cde0233512f8dbbc62238e90c850c310894e3972Wink Saville // Device doesn't support receiving SMS, 116c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang Log.d(TAG, "Received short message on device which doesn't support " 117cde0233512f8dbbc62238e90c850c310894e3972Wink Saville + "receiving SMS. Ignored."); 118c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang return Intents.RESULT_SMS_HANDLED; 119c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang } 120c049f9ad5b4f5bc32f368646e624aef7707b7252John Wang 1219d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // See if we have a network duplicate SMS. 12264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsMessage sms = (SmsMessage) smsb; 1239d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); 1249d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson if (mLastAcknowledgedSmsFingerprint != null && 1259d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { 1269d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson return Intents.RESULT_SMS_HANDLED; 1279d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson } 1289d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // Decode BD stream and set sms variables. 129767a662ecde33c3979bf02b793d392aca0403162Wink Saville sms.parseSms(); 13064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int teleService = sms.getTeleService(); 13164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink boolean handled = false; 132767a662ecde33c3979bf02b793d392aca0403162Wink Saville 133a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh if ((SmsEnvelope.TELESERVICE_VMN == teleService) || 134a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh (SmsEnvelope.TELESERVICE_MWI == teleService)) { 135a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // handling Voicemail 136a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh int voicemailCount = sms.getNumOfVoicemails(); 137a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh Log.d(TAG, "Voicemail count=" + voicemailCount); 138a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // Store the voicemail count in preferences. 139a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( 140b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mContext); 141a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences.Editor editor = sp.edit(); 142a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); 143fa8e271636b9e9b86f247cdb4c91d9ebe9675c27Brad Fitzpatrick editor.apply(); 144b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mPhone.setVoiceMessageWaiting(1, voicemailCount); 145a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh handled = true; 146d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) || 147d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink (SmsEnvelope.TELESERVICE_WEMT == teleService)) && 148d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink sms.isStatusReportMessage()) { 149d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handleCdmaStatusReport(sms); 150d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handled = true; 151a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } else if ((sms.getUserData() == null)) { 15243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) { 153767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "Received SMS without user data"); 154767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 15564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled = true; 156767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 157767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1583960ced4638fdb24ddf904fcb6734dae0959671ejsh if (handled) { 1593960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 1603960ced4638fdb24ddf904fcb6734dae0959671ejsh } 161767a662ecde33c3979bf02b793d392aca0403162Wink Saville 162b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (!mStorageMonitor.isStorageAvailable() && 163b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby sms.getMessageClass() != MessageClass.CLASS_0) { 164a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // It's a storable message and there's no storage available. Bail. 165a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // (See C.S0015-B v2.0 for a description of "Immediate Display" 166a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // messages, which we represent as CLASS_0.) 167a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh return Intents.RESULT_SMS_OUT_OF_MEMORY; 168a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } 169a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh 170c84401fb8b3ed90039bd132b343852303ef88ce6yong liu if (SmsEnvelope.TELESERVICE_WAP == teleService) { 1713960ced4638fdb24ddf904fcb6734dae0959671ejsh return processCdmaWapPdu(sms.getUserData(), sms.messageRef, 1723960ced4638fdb24ddf904fcb6734dae0959671ejsh sms.getOriginatingAddress()); 173767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 174767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1757e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Reject (NAK) any messages with teleservice ids that have 1767e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // not yet been handled and also do not correspond to the two 1777e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // kinds that are processed below. 1787e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink if ((SmsEnvelope.TELESERVICE_WMT != teleService) && 17983fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.TELESERVICE_WEMT != teleService) && 18083fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) { 1817e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return Intents.RESULT_SMS_UNSUPPORTED; 1827e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink } 1837e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink 184b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return dispatchNormalMessage(smsb); 185767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 186767a662ecde33c3979bf02b793d392aca0403162Wink Saville 187767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 188767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Processes inbound messages that are in the WAP-WDP PDU format. See 189767a662ecde33c3979bf02b793d392aca0403162Wink Saville * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 190767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WDP segments are gathered until a datagram completes and gets dispatched. 191767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 192767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param pdu The WAP-WDP PDU segment 1933960ced4638fdb24ddf904fcb6734dae0959671ejsh * @return a result code from {@link Telephony.Sms.Intents}, or 1943960ced4638fdb24ddf904fcb6734dae0959671ejsh * {@link Activity#RESULT_OK} if the message has been broadcast 1953960ced4638fdb24ddf904fcb6734dae0959671ejsh * to applications 196767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 1973960ced4638fdb24ddf904fcb6734dae0959671ejsh protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { 198767a662ecde33c3979bf02b793d392aca0403162Wink Saville int index = 0; 199767a662ecde33c3979bf02b793d392aca0403162Wink Saville 200b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int msgType = pdu[index++]; 201b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (msgType != 0) { 202767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(TAG, "Received a WAP SMS which is not WDP. Discard."); 2033960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 204767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 205b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int totalSegments = pdu[index++]; // >= 1 206b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int segment = pdu[index++]; // >= 0 207767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2085c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause // Only the first segment contains sourcePort and destination Port 209b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int sourcePort = 0; 210b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int destinationPort = 0; 2115c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause if (segment == 0) { 2125c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause //process WDP segment 2135c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort = (0xFF & pdu[index++]) << 8; 2145c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort |= 0xFF & pdu[index++]; 2155c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort = (0xFF & pdu[index++]) << 8; 2165c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort |= 0xFF & pdu[index++]; 217d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Some carriers incorrectly send duplicate port fields in omadm wap pushes. 218d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // If configured, check for that here 219d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (mCheckForDuplicatePortsInOmadmWapPush) { 220d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (checkDuplicatePortOmadmWappush(pdu,index)) { 221d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index = index + 4; // skip duplicate port fields 222d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 223d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 2245c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause } 225767a662ecde33c3979bf02b793d392aca0403162Wink Saville 226767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Lookup all other related parts 227767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address 228767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 229b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments); 230767a662ecde33c3979bf02b793d392aca0403162Wink Saville 231b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby // pass the user data portion of the PDU to the shared handler in SMSDispatcher 232b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby byte[] userData = new byte[pdu.length - index]; 233b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby System.arraycopy(pdu, index, userData, 0, pdu.length - index); 234767a662ecde33c3979bf02b793d392aca0403162Wink Saville 235b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return processMessagePart(userData, address, referenceNumber, segment, totalSegments, 236b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby 0L, destinationPort, true); 237767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 238767a662ecde33c3979bf02b793d392aca0403162Wink Saville 239767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 240145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 2411f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendData(String destAddr, String scAddr, int destPort, 2421f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 2431f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 2441f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, destPort, data, (deliveryIntent != null)); 2451f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 2461f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 2471f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 2481f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 249145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 2501f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendText(String destAddr, String scAddr, String text, 2511f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 2521f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 2531f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, text, (deliveryIntent != null), null); 2541f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 2551f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 2561f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 2571f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 258145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 259b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected TextEncodingDetails calculateLength(CharSequence messageBody, 260b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby boolean use7bitOnly) { 261b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby return SmsMessage.calculateLength(messageBody, use7bitOnly); 262b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } 263767a662ecde33c3979bf02b793d392aca0403162Wink Saville 264b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby /** {@inheritDoc} */ 265b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby @Override 266b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected void sendNewSubmitPdu(String destinationAddress, String scAddress, 267b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby String message, SmsHeader smsHeader, int encoding, 268b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) { 269b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby UserData uData = new UserData(); 270b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.payloadStr = message; 271b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.userDataHeader = smsHeader; 272b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) { 273b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; 274b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } else { // assume UTF-16 275b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncoding = UserData.ENCODING_UNICODE_16; 276b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby } 277b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData.msgEncodingSet = true; 278fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink 279b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby /* By setting the statusReportRequested bit only for the 280b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * last message fragment, this will result in only one 281b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * callback to the sender when that last fragment delivery 282b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby * has been acknowledged. */ 283b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress, 284b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby uData, (deliveryIntent != null) && lastPart); 285767a662ecde33c3979bf02b793d392aca0403162Wink Saville 286b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); 287767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 288767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2891f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, 2901f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 2911f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { 292a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng if (sentIntent != null) { 293a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng try { 294a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); 295a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } catch (CanceledException ex) {} 296a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 29743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato if (false) { 298a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng Log.d(TAG, "Block SMS in Emergency Callback mode"); 299a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 300a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng return; 301a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 3021f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); 303a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 304a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng 305767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 306145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 307767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendSms(SmsTracker tracker) { 308145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby HashMap<String, Object> map = tracker.mData; 309767a662ecde33c3979bf02b793d392aca0403162Wink Saville 310059fe88115ccb70d9870698e490ed5b4c88da50cJake Hamby // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA 311767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte pdu[] = (byte[]) map.get("pdu"); 312767a662ecde33c3979bf02b793d392aca0403162Wink Saville 313767a662ecde33c3979bf02b793d392aca0403162Wink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 314767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.sendCdmaSms(pdu, reply); 315767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 316767a662ecde33c3979bf02b793d392aca0403162Wink Saville 317767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 318145ff609de3206b585819ef974fab20cdc2d9f5eJake Hamby @Override 319b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) { 320117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 321117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang if (inEcm.equals("true")) { 322117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang return; 323117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang } 324117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 325b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby int causeCode = resultToCause(result); 326b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response); 3279d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 328b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby if (causeCode == 0) { 329b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; 330767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 331b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby mLastDispatchedSmsFingerprint = null; 332767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 333767a662ecde33c3979bf02b793d392aca0403162Wink Saville 334b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby private static int resultToCause(int rc) { 335867641ece36e2fd17faaea79cf19506ab17177c6jsh switch (rc) { 3367e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Activity.RESULT_OK: 3377e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_HANDLED: 3387e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Cause code is ignored on success. 3397e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return 0; 3407e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_OUT_OF_MEMORY: 3417e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 3427e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_UNSUPPORTED: 3437e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; 3447e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_GENERIC_ERROR: 3457e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink default: 3463ff560d7ba9fcedc4d388f63b756108a715266f4jsh return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; 347867641ece36e2fd17faaea79cf19506ab17177c6jsh } 348867641ece36e2fd17faaea79cf19506ab17177c6jsh } 349d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 350d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin /** 351d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * Optional check to see if the received WapPush is an OMADM notification with erroneous 352d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * extra port fields. 353d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * - Some carriers make this mistake. 354d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * ex: MSGTYPE-TotalSegments-CurrentSegment 355d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * -SourcePortDestPort-SourcePortDestPort-OMADM PDU 356d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param origPdu The WAP-WDP PDU segment 357d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param index Current Index while parsing the PDU. 358d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. 359d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. 360d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin */ 361b7945cae5ad0feaad09378d0db77f2b3105e5235Jake Hamby private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { 362d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index += 4; 363d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin byte[] omaPdu = new byte[origPdu.length - index]; 364d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); 365d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 366d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); 367d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin int wspIndex = 2; 368d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 369d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process header length field 370d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { 371d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 372d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 373d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 374d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field 375d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 376d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process content type field 377d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeContentType(wspIndex) == false) { 378d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 379d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 380d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 381d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin String mimeType = pduDecoder.getValueString(); 382d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { 383d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen return true; 384d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 385d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 386d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 387767a662ecde33c3979bf02b793d392aca0403162Wink Saville} 388