CdmaSMSDispatcher.java revision d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0
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.AsyncResult; 29767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport android.os.Message; 30117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yangimport android.os.SystemProperties; 31059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport android.preference.PreferenceManager; 323960ced4638fdb24ddf904fcb6734dae0959671ejshimport android.provider.Telephony; 33867641ece36e2fd17faaea79cf19506ab17177c6jshimport android.provider.Telephony.Sms.Intents; 34a1c94ae4f75dab030219069864029f5bd9498fb0Richard Mengimport android.telephony.SmsManager; 35a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jshimport android.telephony.SmsMessage.MessageClass; 36059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport android.util.Config; 37059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport android.util.Log; 38767a662ecde33c3979bf02b793d392aca0403162Wink Saville 39867641ece36e2fd17faaea79cf19506ab17177c6jshimport com.android.internal.telephony.CommandsInterface; 40059fe88115ccb70d9870698e490ed5b4c88da50cJake Hambyimport com.android.internal.telephony.SMSDispatcher; 41767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsHeader; 42767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport com.android.internal.telephony.SmsMessageBase; 431fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscqimport com.android.internal.telephony.SmsMessageBase.TextEncodingDetails; 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; 51767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.ArrayList; 529d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafssonimport java.util.Arrays; 53767a662ecde33c3979bf02b793d392aca0403162Wink Savilleimport java.util.HashMap; 54767a662ecde33c3979bf02b793d392aca0403162Wink Saville 55d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shinimport android.content.res.Resources; 56d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 57767a662ecde33c3979bf02b793d392aca0403162Wink Saville 58767a662ecde33c3979bf02b793d392aca0403162Wink Savillefinal class CdmaSMSDispatcher extends SMSDispatcher { 59767a662ecde33c3979bf02b793d392aca0403162Wink Saville private static final String TAG = "CDMA"; 60767a662ecde33c3979bf02b793d392aca0403162Wink Saville 619d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson private byte[] mLastDispatchedSmsFingerprint; 629d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson private byte[] mLastAcknowledgedSmsFingerprint; 639d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 64d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin private boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean( 65d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin com.android.internal.R.bool.config_duplicate_port_omadm_wappush); 66d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 67767a662ecde33c3979bf02b793d392aca0403162Wink Saville CdmaSMSDispatcher(CDMAPhone phone) { 68767a662ecde33c3979bf02b793d392aca0403162Wink Saville super(phone); 69767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 70767a662ecde33c3979bf02b793d392aca0403162Wink Saville 71767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 72767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Called when a status report is received. This should correspond to 73767a662ecde33c3979bf02b793d392aca0403162Wink Saville * a previously successful SEND. 74767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Is a special GSM function, should never be called in CDMA!! 75767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 76767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param ar AsyncResult passed into the message handler. ar.result should 77767a662ecde33c3979bf02b793d392aca0403162Wink Saville * be a String representing the status report PDU, as ASCII hex. 78767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 79767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void handleStatusReport(AsyncResult ar) { 80767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!"); 81767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 82767a662ecde33c3979bf02b793d392aca0403162Wink Saville 83d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink private void handleCdmaStatusReport(SmsMessage sms) { 84d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { 85d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink SmsTracker tracker = deliveryPendingList.get(i); 86d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink if (tracker.mMessageRef == sms.messageRef) { 87d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink // Found it. Remove from list and broadcast. 88d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink deliveryPendingList.remove(i); 89d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink PendingIntent intent = tracker.mDeliveryIntent; 90d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink Intent fillIn = new Intent(); 91d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink fillIn.putExtra("pdu", sms.getPdu()); 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} */ 1013960ced4638fdb24ddf904fcb6734dae0959671ejsh protected 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 1149d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // See if we have a network duplicate SMS. 11564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsMessage sms = (SmsMessage) smsb; 1169d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mLastDispatchedSmsFingerprint = sms.getIncomingSmsFingerprint(); 1179d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson if (mLastAcknowledgedSmsFingerprint != null && 1189d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson Arrays.equals(mLastDispatchedSmsFingerprint, mLastAcknowledgedSmsFingerprint)) { 1199d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson return Intents.RESULT_SMS_HANDLED; 1209d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson } 1219d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson // Decode BD stream and set sms variables. 122767a662ecde33c3979bf02b793d392aca0403162Wink Saville sms.parseSms(); 12364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int teleService = sms.getTeleService(); 12464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink boolean handled = false; 125767a662ecde33c3979bf02b793d392aca0403162Wink Saville 126a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh if ((SmsEnvelope.TELESERVICE_VMN == teleService) || 127a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh (SmsEnvelope.TELESERVICE_MWI == teleService)) { 128a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // handling Voicemail 129a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh int voicemailCount = sms.getNumOfVoicemails(); 130a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh Log.d(TAG, "Voicemail count=" + voicemailCount); 131a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // Store the voicemail count in preferences. 132a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( 133059fe88115ccb70d9870698e490ed5b4c88da50cJake Hamby mPhone.getContext()); 134a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh SharedPreferences.Editor editor = sp.edit(); 135a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); 136fa8e271636b9e9b86f247cdb4c91d9ebe9675c27Brad Fitzpatrick editor.apply(); 137a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); 138a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh handled = true; 139d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) || 140d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink (SmsEnvelope.TELESERVICE_WEMT == teleService)) && 141d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink sms.isStatusReportMessage()) { 142d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handleCdmaStatusReport(sms); 143d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink handled = true; 144a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } else if ((sms.getUserData() == null)) { 145767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (Config.LOGD) { 146767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "Received SMS without user data"); 147767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 14864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink handled = true; 149767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 150767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1513960ced4638fdb24ddf904fcb6734dae0959671ejsh if (handled) { 1523960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 1533960ced4638fdb24ddf904fcb6734dae0959671ejsh } 154767a662ecde33c3979bf02b793d392aca0403162Wink Saville 155a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { 156a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // It's a storable message and there's no storage available. Bail. 157a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // (See C.S0015-B v2.0 for a description of "Immediate Display" 158a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh // messages, which we represent as CLASS_0.) 159a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh return Intents.RESULT_SMS_OUT_OF_MEMORY; 160a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh } 161a01726a7fdd872cd8e1e8a9dfa52fb9cdbf01019jsh 162c84401fb8b3ed90039bd132b343852303ef88ce6yong liu if (SmsEnvelope.TELESERVICE_WAP == teleService) { 1633960ced4638fdb24ddf904fcb6734dae0959671ejsh return processCdmaWapPdu(sms.getUserData(), sms.messageRef, 1643960ced4638fdb24ddf904fcb6734dae0959671ejsh sms.getOriginatingAddress()); 165767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 166767a662ecde33c3979bf02b793d392aca0403162Wink Saville 1677e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Reject (NAK) any messages with teleservice ids that have 1687e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // not yet been handled and also do not correspond to the two 1697e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // kinds that are processed below. 1707e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink if ((SmsEnvelope.TELESERVICE_WMT != teleService) && 17183fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.TELESERVICE_WEMT != teleService) && 17283fd7b0d53f2fecb5b92cb911910e07659e246caJohn Joseph (SmsEnvelope.MESSAGE_TYPE_BROADCAST != sms.getMessageType())) { 1737e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return Intents.RESULT_SMS_UNSUPPORTED; 1747e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink } 1757e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink 1767e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink /* 17764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): Why are we using a getter method for this 17864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * (and for so many other sms fields)? Trivial getters and 17964c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * setters like this are direct violations of the style guide. 180059fe88115ccb70d9870698e490ed5b4c88da50cJake Hamby * If the purpose is to protect against writes (by not 18164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * providing a setter) then any protection is illusory (and 18264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * hence bad) for cases where the values are not primitives, 18364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * such as this call for the header. Since this is an issue 18464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * with the public API it cannot be changed easily, but maybe 18564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * something can be done eventually. 18664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 18764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader smsHeader = sms.getUserDataHeader(); 18864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 1897e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink /* 19064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): Since both CDMA and GSM use the same header 19164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * format, this dispatch processing is naturally identical, 19264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * and code should probably not be replicated explicitly. 19364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 1947e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink 19564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // See if message is partial or port addressed. 19664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if ((smsHeader == null) || (smsHeader.concatRef == null)) { 19764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Message is not partial (not part of concatenated sequence). 198767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[][] pdus = new byte[1][]; 199767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[0] = sms.getPdu(); 200767a662ecde33c3979bf02b793d392aca0403162Wink Saville 20131fd22923aaefc85652a5b5939c6d4aa6fa289e2jsh if (smsHeader != null && smsHeader.portAddrs != null) { 20264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { 20364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // GSM-style WAP indication 2043960ced4638fdb24ddf904fcb6734dae0959671ejsh return mWapPush.dispatchWapPdu(sms.getUserData()); 2053960ced4638fdb24ddf904fcb6734dae0959671ejsh } else { 2063960ced4638fdb24ddf904fcb6734dae0959671ejsh // The message was sent to a port, so concoct a URI for it. 2073960ced4638fdb24ddf904fcb6734dae0959671ejsh dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); 208767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 209767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 21064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Normal short and non-port-addressed message, dispatch it. 211767a662ecde33c3979bf02b793d392aca0403162Wink Saville dispatchPdus(pdus); 212767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 2133960ced4638fdb24ddf904fcb6734dae0959671ejsh return Activity.RESULT_OK; 214767a662ecde33c3979bf02b793d392aca0403162Wink Saville } else { 21564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink // Process the message part. 2163960ced4638fdb24ddf904fcb6734dae0959671ejsh return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs); 217767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 218767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 219767a662ecde33c3979bf02b793d392aca0403162Wink Saville 220767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** 221767a662ecde33c3979bf02b793d392aca0403162Wink Saville * Processes inbound messages that are in the WAP-WDP PDU format. See 222767a662ecde33c3979bf02b793d392aca0403162Wink Saville * wap-259-wdp-20010614-a section 6.5 for details on the WAP-WDP PDU format. 223767a662ecde33c3979bf02b793d392aca0403162Wink Saville * WDP segments are gathered until a datagram completes and gets dispatched. 224767a662ecde33c3979bf02b793d392aca0403162Wink Saville * 225767a662ecde33c3979bf02b793d392aca0403162Wink Saville * @param pdu The WAP-WDP PDU segment 2263960ced4638fdb24ddf904fcb6734dae0959671ejsh * @return a result code from {@link Telephony.Sms.Intents}, or 2273960ced4638fdb24ddf904fcb6734dae0959671ejsh * {@link Activity#RESULT_OK} if the message has been broadcast 2283960ced4638fdb24ddf904fcb6734dae0959671ejsh * to applications 229767a662ecde33c3979bf02b793d392aca0403162Wink Saville */ 2303960ced4638fdb24ddf904fcb6734dae0959671ejsh protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) { 231767a662ecde33c3979bf02b793d392aca0403162Wink Saville int segment; 232767a662ecde33c3979bf02b793d392aca0403162Wink Saville int totalSegments; 233767a662ecde33c3979bf02b793d392aca0403162Wink Saville int index = 0; 234767a662ecde33c3979bf02b793d392aca0403162Wink Saville int msgType; 235767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2365c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause int sourcePort = 0; 2375c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause int destinationPort = 0; 238767a662ecde33c3979bf02b793d392aca0403162Wink Saville 239767a662ecde33c3979bf02b793d392aca0403162Wink Saville msgType = pdu[index++]; 240767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (msgType != 0){ 241767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.w(TAG, "Received a WAP SMS which is not WDP. Discard."); 2423960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 243767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 244767a662ecde33c3979bf02b793d392aca0403162Wink Saville totalSegments = pdu[index++]; // >=1 245767a662ecde33c3979bf02b793d392aca0403162Wink Saville segment = pdu[index++]; // >=0 246767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2475c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause // Only the first segment contains sourcePort and destination Port 2485c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause if (segment == 0) { 2495c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause //process WDP segment 2505c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort = (0xFF & pdu[index++]) << 8; 2515c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause sourcePort |= 0xFF & pdu[index++]; 2525c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort = (0xFF & pdu[index++]) << 8; 2535c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort |= 0xFF & pdu[index++]; 254d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Some carriers incorrectly send duplicate port fields in omadm wap pushes. 255d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // If configured, check for that here 256d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (mCheckForDuplicatePortsInOmadmWapPush) { 257d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (checkDuplicatePortOmadmWappush(pdu,index)) { 258d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index = index + 4; // skip duplicate port fields 259d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 260d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 2615c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause } 262767a662ecde33c3979bf02b793d392aca0403162Wink Saville 263767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Lookup all other related parts 264767a662ecde33c3979bf02b793d392aca0403162Wink Saville StringBuilder where = new StringBuilder("reference_number ="); 265767a662ecde33c3979bf02b793d392aca0403162Wink Saville where.append(referenceNumber); 266767a662ecde33c3979bf02b793d392aca0403162Wink Saville where.append(" AND address = ?"); 267767a662ecde33c3979bf02b793d392aca0403162Wink Saville String[] whereArgs = new String[] {address}; 268767a662ecde33c3979bf02b793d392aca0403162Wink Saville 269767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address 270767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", src-port = " + sourcePort + ", dst-port = " + destinationPort 271767a662ecde33c3979bf02b793d392aca0403162Wink Saville + ", ID = " + referenceNumber + ", segment# = " + segment + "/" + totalSegments); 272767a662ecde33c3979bf02b793d392aca0403162Wink Saville 273767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[][] pdus = null; 274767a662ecde33c3979bf02b793d392aca0403162Wink Saville Cursor cursor = null; 275767a662ecde33c3979bf02b793d392aca0403162Wink Saville try { 276767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null); 277767a662ecde33c3979bf02b793d392aca0403162Wink Saville int cursorCount = cursor.getCount(); 278767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (cursorCount != totalSegments - 1) { 279767a662ecde33c3979bf02b793d392aca0403162Wink Saville // We don't have all the parts yet, store this one away 280767a662ecde33c3979bf02b793d392aca0403162Wink Saville ContentValues values = new ContentValues(); 281ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby values.put("date", (long) 0); 282767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("pdu", HexDump.toHexString(pdu, index, pdu.length - index)); 283767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("address", address); 284767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("reference_number", referenceNumber); 285767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("count", totalSegments); 286767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("sequence", segment); 287767a662ecde33c3979bf02b793d392aca0403162Wink Saville values.put("destination_port", destinationPort); 288767a662ecde33c3979bf02b793d392aca0403162Wink Saville 289767a662ecde33c3979bf02b793d392aca0403162Wink Saville mResolver.insert(mRawUri, values); 290767a662ecde33c3979bf02b793d392aca0403162Wink Saville 2913960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_HANDLED; 292767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 293767a662ecde33c3979bf02b793d392aca0403162Wink Saville 294767a662ecde33c3979bf02b793d392aca0403162Wink Saville // All the parts are in place, deal with them 295767a662ecde33c3979bf02b793d392aca0403162Wink Saville int pduColumn = cursor.getColumnIndex("pdu"); 296767a662ecde33c3979bf02b793d392aca0403162Wink Saville int sequenceColumn = cursor.getColumnIndex("sequence"); 297767a662ecde33c3979bf02b793d392aca0403162Wink Saville 298767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus = new byte[totalSegments][]; 299767a662ecde33c3979bf02b793d392aca0403162Wink Saville for (int i = 0; i < cursorCount; i++) { 300767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor.moveToNext(); 301767a662ecde33c3979bf02b793d392aca0403162Wink Saville int cursorSequence = (int)cursor.getLong(sequenceColumn); 3025c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause // Read the destination port from the first segment 3035c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause if (cursorSequence == 0) { 3045c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause int destinationPortColumn = cursor.getColumnIndex("destination_port"); 3055c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause destinationPort = (int)cursor.getLong(destinationPortColumn); 3065c7d9e8194900a2b1699cd57f95b22ca5f7b9be2David Krause } 307767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[cursorSequence] = HexDump.hexStringToByteArray( 308767a662ecde33c3979bf02b793d392aca0403162Wink Saville cursor.getString(pduColumn)); 309767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 310767a662ecde33c3979bf02b793d392aca0403162Wink Saville // The last part will be added later 311767a662ecde33c3979bf02b793d392aca0403162Wink Saville 312767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Remove the parts from the database 313767a662ecde33c3979bf02b793d392aca0403162Wink Saville mResolver.delete(mRawUri, where.toString(), whereArgs); 314767a662ecde33c3979bf02b793d392aca0403162Wink Saville } catch (SQLException e) { 315767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.e(TAG, "Can't access multipart SMS database", e); 3163960ced4638fdb24ddf904fcb6734dae0959671ejsh return Intents.RESULT_SMS_GENERIC_ERROR; 317767a662ecde33c3979bf02b793d392aca0403162Wink Saville } finally { 318767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (cursor != null) cursor.close(); 319767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 320767a662ecde33c3979bf02b793d392aca0403162Wink Saville 321767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Build up the data stream 322767a662ecde33c3979bf02b793d392aca0403162Wink Saville ByteArrayOutputStream output = new ByteArrayOutputStream(); 32370f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson for (int i = 0; i < totalSegments; i++) { 324767a662ecde33c3979bf02b793d392aca0403162Wink Saville // reassemble the (WSP-)pdu 32570f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson if (i == segment) { 32670f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson // This one isn't in the DB, so add it 32770f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson output.write(pdu, index, pdu.length - index); 32870f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson } else { 32970f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson output.write(pdus[i], 0, pdus[i].length); 33070f74b79c3e4c88e0e7b747796f76187e4ea8259Christian Gustafsson } 331767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 332767a662ecde33c3979bf02b793d392aca0403162Wink Saville 333767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte[] datagram = output.toByteArray(); 334767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Dispatch the PDU to applications 335767a662ecde33c3979bf02b793d392aca0403162Wink Saville switch (destinationPort) { 336767a662ecde33c3979bf02b793d392aca0403162Wink Saville case SmsHeader.PORT_WAP_PUSH: 337767a662ecde33c3979bf02b793d392aca0403162Wink Saville // Handle the PUSH 3383960ced4638fdb24ddf904fcb6734dae0959671ejsh return mWapPush.dispatchWapPdu(datagram); 339767a662ecde33c3979bf02b793d392aca0403162Wink Saville 340767a662ecde33c3979bf02b793d392aca0403162Wink Saville default:{ 341767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus = new byte[1][]; 342767a662ecde33c3979bf02b793d392aca0403162Wink Saville pdus[0] = datagram; 343767a662ecde33c3979bf02b793d392aca0403162Wink Saville // The messages were sent to any other WAP port 344767a662ecde33c3979bf02b793d392aca0403162Wink Saville dispatchPortAddressedPdus(pdus, destinationPort); 3453960ced4638fdb24ddf904fcb6734dae0959671ejsh return Activity.RESULT_OK; 346767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 347767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 348767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 349767a662ecde33c3979bf02b793d392aca0403162Wink Saville 350767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 3511f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendData(String destAddr, String scAddr, int destPort, 3521f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { 3531f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 3541f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, destPort, data, (deliveryIntent != null)); 3551f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 3561f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 3571f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 3581f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 3591f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendText(String destAddr, String scAddr, String text, 3601f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 3611f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu( 3621f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink scAddr, destAddr, text, (deliveryIntent != null), null); 3631f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendSubmitPdu(pdu, sentIntent, deliveryIntent); 3641f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink } 3651f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink 3661f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink /** {@inheritDoc} */ 36764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink protected void sendMultipartText(String destAddr, String scAddr, 368767a662ecde33c3979bf02b793d392aca0403162Wink Saville ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, 369767a662ecde33c3979bf02b793d392aca0403162Wink Saville ArrayList<PendingIntent> deliveryIntents) { 370767a662ecde33c3979bf02b793d392aca0403162Wink Saville 37164c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink /** 37264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * TODO(cleanup): There is no real code difference between 37364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * this and the GSM version, and hence it should be moved to 37464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * the base class or consolidated somehow, provided calling 37564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink * the proper submitpdu stuff can be arranged. 37664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink */ 377767a662ecde33c3979bf02b793d392aca0403162Wink Saville 37864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink int refNumber = getNextConcatenatedRef() & 0x00FF; 3791fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq int msgCount = parts.size(); 3801fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN; 3811fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq 3821fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq for (int i = 0; i < msgCount; i++) { 3831fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false); 3841fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq if (encoding != details.codeUnitSize 3851fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN 3861fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) { 3871fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq encoding = details.codeUnitSize; 3881fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq } 3891fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq } 390767a662ecde33c3979bf02b793d392aca0403162Wink Saville 3911fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq for (int i = 0; i < msgCount; i++) { 39264c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); 39364c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.refNumber = refNumber; 39464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.seqNumber = i + 1; // 1-based sequence 39564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.msgCount = msgCount; 39664c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink concatRef.isEightBits = true; 39764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink SmsHeader smsHeader = new SmsHeader(); 39864c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink smsHeader.concatRef = concatRef; 399767a662ecde33c3979bf02b793d392aca0403162Wink Saville 40064c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink PendingIntent sentIntent = null; 401767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (sentIntents != null && sentIntents.size() > i) { 402767a662ecde33c3979bf02b793d392aca0403162Wink Saville sentIntent = sentIntents.get(i); 403767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 40464c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink 40564c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink PendingIntent deliveryIntent = null; 406767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (deliveryIntents != null && deliveryIntents.size() > i) { 407767a662ecde33c3979bf02b793d392aca0403162Wink Saville deliveryIntent = deliveryIntents.get(i); 408767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 409767a662ecde33c3979bf02b793d392aca0403162Wink Saville 410fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink UserData uData = new UserData(); 411fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink uData.payloadStr = parts.get(i); 412fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink uData.userDataHeader = smsHeader; 4131fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) { 4141fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET; 4151fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq } else { // assume UTF-16 4161fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq uData.msgEncoding = UserData.ENCODING_UNICODE_16; 4171fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq } 4181fa7fae1399f735ea15242484fb5def187e07fdeGilles Duboscq uData.msgEncodingSet = true; 419fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink 420d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink /* By setting the statusReportRequested bit only for the 421d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink * last message fragment, this will result in only one 422d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink * callback to the sender when that last fragment delivery 423d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink * has been acknowledged. */ 424fc78f358cb1d1cee99758bcd6ef998a122ef27c9Tammo Spalink SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr, 425d304ae583d862250a21b5949fc3dbdf3af1febacTammo Spalink uData, (deliveryIntent != null) && (i == (msgCount - 1))); 426767a662ecde33c3979bf02b793d392aca0403162Wink Saville 42764c499113a758cf80cddfd4d0183f944a1a6645aTammo Spalink sendSubmitPdu(submitPdu, sentIntent, deliveryIntent); 428767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 429767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 430767a662ecde33c3979bf02b793d392aca0403162Wink Saville 4311f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu, 4321f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink PendingIntent sentIntent, PendingIntent deliveryIntent) { 4331f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) { 434a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng if (sentIntent != null) { 435a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng try { 436a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); 437a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } catch (CanceledException ex) {} 438a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 439a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng if (Config.LOGD) { 440a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng Log.d(TAG, "Block SMS in Emergency Callback mode"); 441a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 442a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng return; 443a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 4441f952a178db86559ff4bab79c4a9b5fae18096bfTammo Spalink sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent); 445a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng } 446a1c94ae4f75dab030219069864029f5bd9498fb0Richard Meng 447767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 448767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendSms(SmsTracker tracker) { 449767a662ecde33c3979bf02b793d392aca0403162Wink Saville HashMap map = tracker.mData; 450767a662ecde33c3979bf02b793d392aca0403162Wink Saville 451059fe88115ccb70d9870698e490ed5b4c88da50cJake Hamby // byte smsc[] = (byte[]) map.get("smsc"); // unused for CDMA 452767a662ecde33c3979bf02b793d392aca0403162Wink Saville byte pdu[] = (byte[]) map.get("pdu"); 453767a662ecde33c3979bf02b793d392aca0403162Wink Saville 454767a662ecde33c3979bf02b793d392aca0403162Wink Saville Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); 455767a662ecde33c3979bf02b793d392aca0403162Wink Saville 456767a662ecde33c3979bf02b793d392aca0403162Wink Saville mCm.sendCdmaSms(pdu, reply); 457767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 458767a662ecde33c3979bf02b793d392aca0403162Wink Saville 459767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 460767a662ecde33c3979bf02b793d392aca0403162Wink Saville protected void sendMultipartSms (SmsTracker tracker) { 461767a662ecde33c3979bf02b793d392aca0403162Wink Saville Log.d(TAG, "TODO: CdmaSMSDispatcher.sendMultipartSms not implemented"); 462767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 463767a662ecde33c3979bf02b793d392aca0403162Wink Saville 464767a662ecde33c3979bf02b793d392aca0403162Wink Saville /** {@inheritDoc} */ 465867641ece36e2fd17faaea79cf19506ab17177c6jsh protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){ 466767a662ecde33c3979bf02b793d392aca0403162Wink Saville // FIXME unit test leaves cm == null. this should change 467117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 468117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false"); 469117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang if (inEcm.equals("true")) { 470117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang return; 471117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang } 472117eace23924f575877ae8ecbb899af22e6f16c0Cheng Yang 473767a662ecde33c3979bf02b793d392aca0403162Wink Saville if (mCm != null) { 4749d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson int causeCode = resultToCause(result); 4759d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response); 4769d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson 4779d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson if (causeCode == 0) { 4789d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint; 4799d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson } 4809d34319f1ce5be4124a0b6293162587f4573496fChristian Gustafsson mLastDispatchedSmsFingerprint = null; 481767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 482767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 483767a662ecde33c3979bf02b793d392aca0403162Wink Saville 484ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby protected void handleBroadcastSms(AsyncResult ar) { 485ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby // Not supported 486ab79ee4adcbc6eb9fb9c509766753f65d3857739Jake Hamby Log.e(TAG, "Error! Not implemented for CDMA."); 487767a662ecde33c3979bf02b793d392aca0403162Wink Saville } 488767a662ecde33c3979bf02b793d392aca0403162Wink Saville 489867641ece36e2fd17faaea79cf19506ab17177c6jsh private int resultToCause(int rc) { 490867641ece36e2fd17faaea79cf19506ab17177c6jsh switch (rc) { 4917e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Activity.RESULT_OK: 4927e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_HANDLED: 4937e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink // Cause code is ignored on success. 4947e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return 0; 4957e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_OUT_OF_MEMORY: 4967e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_RESOURCE_SHORTAGE; 4977e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_UNSUPPORTED: 4987e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink return CommandsInterface.CDMA_SMS_FAIL_CAUSE_INVALID_TELESERVICE_ID; 4997e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink case Intents.RESULT_SMS_GENERIC_ERROR: 5007e207afd497f8822ca34babe1d9cd1f6d5402fadTammo Spalink default: 5013ff560d7ba9fcedc4d388f63b756108a715266f4jsh return CommandsInterface.CDMA_SMS_FAIL_CAUSE_ENCODING_PROBLEM; 502867641ece36e2fd17faaea79cf19506ab17177c6jsh } 503867641ece36e2fd17faaea79cf19506ab17177c6jsh } 504d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 505d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin /** 506d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * Optional check to see if the received WapPush is an OMADM notification with erroneous 507d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * extra port fields. 508d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * - Some carriers make this mistake. 509d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * ex: MSGTYPE-TotalSegments-CurrentSegment 510d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * -SourcePortDestPort-SourcePortDestPort-OMADM PDU 511d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param origPdu The WAP-WDP PDU segment 512d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @param index Current Index while parsing the PDU. 513d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * @return True if OrigPdu is OmaDM Push Message which has duplicate ports. 514d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin * False if OrigPdu is NOT OmaDM Push Message which has duplicate ports. 515d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin */ 516d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin private boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) { 517d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin index += 4; 518d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin byte[] omaPdu = new byte[origPdu.length - index]; 519d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length); 520d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 521d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin WspTypeDecoder pduDecoder = new WspTypeDecoder(omaPdu); 522d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin int wspIndex = 2; 523d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 524d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process header length field 525d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeUintvarInteger(wspIndex) == false) { 526d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 527d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 528d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 529d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin wspIndex += pduDecoder.getDecodedDataLength(); // advance to next field 530d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 531d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin // Process content type field 532d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin if (pduDecoder.decodeContentType(wspIndex) == false) { 533d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 534d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 535d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin 536d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin String mimeType = pduDecoder.getValueString(); 537d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_SYNCML_NOTI)) { 538d8f9a83cab34de38981dc3ba5ca9df8dda02dbc0Marco Nelissen return true; 539d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 540d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin return false; 541d027329cd6105c05c157e3858a170e4f04eb0e3eSoojung Shin } 542767a662ecde33c3979bf02b793d392aca0403162Wink Saville} 543